Imported Upstream version 1.46.0 13/269213/1 upstream/1.46.0
authorSeonah Moon <seonah1.moon@samsung.com>
Tue, 11 Jan 2022 09:46:06 +0000 (18:46 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Tue, 11 Jan 2022 09:46:28 +0000 (18:46 +0900)
Change-Id: I07607300efdae9a2daf1ced9415a2b930b30f533

574 files changed:
AUTHORS
CMakeLists.txt
CMakeOptions.txt
ChangeLog
INSTALL
Makefile.am
Makefile.in
README.rst
aclocal.m4
bpf/CMakeLists.txt [new file with mode: 0644]
bpf/Makefile.am [new file with mode: 0644]
bpf/Makefile.in [new file with mode: 0644]
bpf/reuseport_kern.c [new file with mode: 0644]
cmake/FindLibbpf.cmake [new file with mode: 0644]
cmake/FindLibnghttp3.cmake [new file with mode: 0644]
cmake/FindLibngtcp2.cmake [new file with mode: 0644]
cmake/FindLibngtcp2_crypto_openssl.cmake [new file with mode: 0644]
cmake/FindSpdylay.cmake [deleted file]
cmake/FindSystemd.cmake [new file with mode: 0644]
cmakeconfig.h.in
compile
config.h.in
configure
configure.ac
contrib/Makefile.in
depcomp
doc/CMakeLists.txt
doc/Makefile.am
doc/Makefile.in
doc/_exts/rubydomain/LICENSE.rubydomain [moved from doc/_exts/sphinxcontrib/LICENSE.rubydomain with 100% similarity]
doc/_exts/rubydomain/__init__.py [moved from doc/_exts/sphinxcontrib/__init__.py with 100% similarity]
doc/_exts/rubydomain/rubydomain.py [moved from doc/_exts/sphinxcontrib/rubydomain.py with 95% similarity]
doc/_themes/sphinx_rtd_theme/__init__.py
doc/_themes/sphinx_rtd_theme/breadcrumbs.html
doc/_themes/sphinx_rtd_theme/footer.html
doc/_themes/sphinx_rtd_theme/layout.html
doc/_themes/sphinx_rtd_theme/layout_old.html [deleted file]
doc/_themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/sphinx.pot [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.mo [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.po [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/search.html
doc/_themes/sphinx_rtd_theme/searchbox.html
doc/_themes/sphinx_rtd_theme/static/css/badge_only.css
doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff2 [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff2 [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.eot [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.svg [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.ttf [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff2 [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff2 [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff2 [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff2 [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff2 [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/css/theme.css
doc/_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf [deleted file]
doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot [deleted file]
doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg [deleted file]
doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf [deleted file]
doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff [deleted file]
doc/_themes/sphinx_rtd_theme/static/js/badge_only.js [new file with mode: 0644]
doc/_themes/sphinx_rtd_theme/static/js/theme.js
doc/_themes/sphinx_rtd_theme/theme.conf
doc/_themes/sphinx_rtd_theme/versions.html
doc/bash_completion/h2load
doc/bash_completion/nghttp
doc/bash_completion/nghttpd
doc/bash_completion/nghttpx
doc/conf.py.in
doc/enums.rst
doc/h2load.1
doc/h2load.1.rst
doc/macros.rst
doc/mkapiref.py
doc/nghttp.1
doc/nghttp2_check_authority.rst
doc/nghttp2_check_method.rst [new file with mode: 0644]
doc/nghttp2_check_path.rst [new file with mode: 0644]
doc/nghttp2_hd_deflate_change_table_size.rst
doc/nghttp2_hd_deflate_hd.rst
doc/nghttp2_hd_deflate_hd_vec.rst
doc/nghttp2_hd_deflate_new.rst
doc/nghttp2_hd_inflate_change_table_size.rst
doc/nghttp2_hd_inflate_hd.rst
doc/nghttp2_hd_inflate_hd2.rst
doc/nghttp2_hd_inflate_new.rst
doc/nghttp2_option_new.rst
doc/nghttp2_option_set_max_send_header_block_length.rst
doc/nghttp2_option_set_no_auto_ping_ack.rst
doc/nghttp2_option_set_no_recv_client_magic.rst
doc/nghttp2_pack_settings_payload.rst
doc/nghttp2_session_callbacks_new.rst
doc/nghttp2_session_callbacks_set_send_data_callback.rst
doc/nghttp2_session_change_stream_priority.rst
doc/nghttp2_session_client_new.rst
doc/nghttp2_session_client_new2.rst
doc/nghttp2_session_client_new3.rst
doc/nghttp2_session_consume.rst
doc/nghttp2_session_consume_connection.rst
doc/nghttp2_session_consume_stream.rst
doc/nghttp2_session_create_idle_stream.rst
doc/nghttp2_session_mem_recv.rst
doc/nghttp2_session_mem_send.rst
doc/nghttp2_session_recv.rst
doc/nghttp2_session_resume_data.rst
doc/nghttp2_session_send.rst
doc/nghttp2_session_server_new.rst
doc/nghttp2_session_server_new2.rst
doc/nghttp2_session_server_new3.rst
doc/nghttp2_session_set_local_window_size.rst
doc/nghttp2_session_set_next_stream_id.rst
doc/nghttp2_session_set_stream_user_data.rst
doc/nghttp2_session_terminate_session.rst
doc/nghttp2_session_terminate_session2.rst
doc/nghttp2_session_upgrade.rst
doc/nghttp2_session_upgrade2.rst
doc/nghttp2_stream_get_state.rst
doc/nghttp2_submit_altsvc.rst
doc/nghttp2_submit_data.rst
doc/nghttp2_submit_extension.rst
doc/nghttp2_submit_goaway.rst
doc/nghttp2_submit_headers.rst
doc/nghttp2_submit_origin.rst
doc/nghttp2_submit_ping.rst
doc/nghttp2_submit_priority.rst
doc/nghttp2_submit_push_promise.rst
doc/nghttp2_submit_request.rst
doc/nghttp2_submit_response.rst
doc/nghttp2_submit_rst_stream.rst
doc/nghttp2_submit_settings.rst
doc/nghttp2_submit_shutdown_notice.rst
doc/nghttp2_submit_trailer.rst
doc/nghttp2_submit_window_update.rst
doc/nghttpd.1
doc/nghttpx.1
doc/nghttpx.1.rst
doc/programmers-guide.rst
doc/sources/contribute.rst
doc/sources/h2load-howto.rst
doc/sources/index.rst
doc/sources/nghttpx-howto.rst
doc/sources/python-apiref.rst
doc/sources/security.rst [new file with mode: 0644]
doc/types.rst
examples/Makefile.am
examples/Makefile.in
examples/client.c
examples/deflate.c
examples/libevent-client.c
examples/libevent-server.c
install-sh
integration-tests/Makefile.in
integration-tests/nghttpx_http1_test.go
integration-tests/nghttpx_http2_test.go
integration-tests/setenv
integration-tests/setenv.in
lib/Makefile.am
lib/Makefile.in
lib/includes/Makefile.in
lib/includes/nghttp2/nghttp2.h
lib/includes/nghttp2/nghttp2ver.h
lib/nghttp2_buf.c
lib/nghttp2_frame.c
lib/nghttp2_frame.h
lib/nghttp2_helper.c
lib/nghttp2_http.c
lib/nghttp2_map.c
lib/nghttp2_map.h
lib/nghttp2_session.c
lib/nghttp2_stream.c
lib/nghttp2_stream.h
ltmain.sh [changed mode: 0644->0755]
m4/ax_python_devel.m4
m4/libtool.m4
missing
python/Makefile.am
python/Makefile.in
python/nghttp2.pyx
script/Makefile.in
src/CMakeLists.txt
src/HttpServer.cc
src/HttpServer.h
src/Makefile.am
src/Makefile.in
src/allocator.h
src/asio_common.cc
src/asio_server_connection.h
src/h2load.cc
src/h2load.h
src/h2load_http2_session.cc
src/h2load_http3_session.cc [new file with mode: 0644]
src/h2load_http3_session.h [new file with mode: 0644]
src/h2load_quic.cc [new file with mode: 0644]
src/h2load_quic.h [new file with mode: 0644]
src/http2.cc
src/http2.h
src/http3.cc [new file with mode: 0644]
src/http3.h [new file with mode: 0644]
src/includes/Makefile.in
src/includes/nghttp2/asio_http2_client.h
src/includes/nghttp2/asio_http2_server.h
src/memchunk.h
src/nghttp.cc
src/quic.cc [new file with mode: 0644]
src/quic.h [new file with mode: 0644]
src/shrpx-unittest.cc
src/shrpx.cc
src/shrpx.h
src/shrpx_client_handler.cc
src/shrpx_client_handler.h
src/shrpx_config.cc
src/shrpx_config.h
src/shrpx_connection.cc
src/shrpx_connection_handler.cc
src/shrpx_connection_handler.h
src/shrpx_downstream.cc
src/shrpx_downstream.h
src/shrpx_downstream_test.cc
src/shrpx_http.cc
src/shrpx_http.h
src/shrpx_http2_session.cc
src/shrpx_http2_upstream.cc
src/shrpx_http3_upstream.cc [new file with mode: 0644]
src/shrpx_http3_upstream.h [new file with mode: 0644]
src/shrpx_http_downstream_connection.cc
src/shrpx_http_test.cc
src/shrpx_http_test.h
src/shrpx_https_upstream.cc
src/shrpx_log.cc
src/shrpx_log.h
src/shrpx_memcached_connection.cc
src/shrpx_mruby.cc
src/shrpx_mruby_module_env.cc
src/shrpx_null_downstream_connection.cc [new file with mode: 0644]
src/shrpx_null_downstream_connection.h [new file with mode: 0644]
src/shrpx_quic.cc [new file with mode: 0644]
src/shrpx_quic.h [new file with mode: 0644]
src/shrpx_quic_connection_handler.cc [new file with mode: 0644]
src/shrpx_quic_connection_handler.h [new file with mode: 0644]
src/shrpx_quic_listener.cc [new file with mode: 0644]
src/shrpx_quic_listener.h [new file with mode: 0644]
src/shrpx_rate_limit.cc
src/shrpx_signal.cc
src/shrpx_signal.h
src/shrpx_tls.cc
src/shrpx_tls.h
src/shrpx_tls_test.cc
src/shrpx_worker.cc
src/shrpx_worker.h
src/shrpx_worker_process.cc
src/shrpx_worker_process.h
src/ssl_compat.h
src/template.h
src/tls.cc
src/tls.h
src/util.cc
src/util.h
src/util_test.cc
src/util_test.h
test-driver
tests/Makefile.in
tests/failmalloc.c
tests/main.c
tests/nghttp2_map_test.c
tests/nghttp2_map_test.h
tests/nghttp2_session_test.c
tests/nghttp2_session_test.h
tests/testdata/Makefile.in
third-party/Makefile.am
third-party/Makefile.in
third-party/build_config.rb
third-party/llhttp/include/llhttp.h
third-party/llhttp/src/api.c
third-party/llhttp/src/http.c
third-party/llhttp/src/llhttp.c
third-party/mruby/AUTHORS
third-party/mruby/CONTRIBUTING.md
third-party/mruby/Doxyfile [new file with mode: 0644]
third-party/mruby/LICENSE
third-party/mruby/Makefile
third-party/mruby/README.md
third-party/mruby/Rakefile
third-party/mruby/appveyor.yml
third-party/mruby/appveyor_config.rb
third-party/mruby/build_config.rb
third-party/mruby/doc/guides/compile.md
third-party/mruby/doc/guides/debugger.md
third-party/mruby/doc/guides/mrbconf.md
third-party/mruby/doc/guides/mrbgems.md
third-party/mruby/doc/limitations.md
third-party/mruby/doc/mruby_logo_red_icon.png [new file with mode: 0644]
third-party/mruby/doc/opcode.md
third-party/mruby/examples/targets/build_config_ArduinoDue.rb
third-party/mruby/examples/targets/build_config_IntelEdison.rb
third-party/mruby/examples/targets/build_config_IntelGalileo.rb
third-party/mruby/examples/targets/build_config_RX630.rb
third-party/mruby/examples/targets/build_config_chipKITMax32.rb
third-party/mruby/examples/targets/build_config_dreamcast_shelf.rb [new file with mode: 0644]
third-party/mruby/include/mrbconf.h
third-party/mruby/include/mruby.h
third-party/mruby/include/mruby/array.h
third-party/mruby/include/mruby/boxing_nan.h
third-party/mruby/include/mruby/boxing_no.h
third-party/mruby/include/mruby/boxing_word.h
third-party/mruby/include/mruby/class.h
third-party/mruby/include/mruby/common.h
third-party/mruby/include/mruby/compile.h
third-party/mruby/include/mruby/data.h
third-party/mruby/include/mruby/debug.h
third-party/mruby/include/mruby/dump.h
third-party/mruby/include/mruby/error.h
third-party/mruby/include/mruby/gc.h
third-party/mruby/include/mruby/hash.h
third-party/mruby/include/mruby/irep.h
third-party/mruby/include/mruby/istruct.h
third-party/mruby/include/mruby/khash.h
third-party/mruby/include/mruby/numeric.h
third-party/mruby/include/mruby/object.h
third-party/mruby/include/mruby/opcode.h
third-party/mruby/include/mruby/ops.h
third-party/mruby/include/mruby/proc.h
third-party/mruby/include/mruby/range.h
third-party/mruby/include/mruby/re.h
third-party/mruby/include/mruby/string.h
third-party/mruby/include/mruby/throw.h
third-party/mruby/include/mruby/value.h
third-party/mruby/include/mruby/variable.h
third-party/mruby/include/mruby/version.h
third-party/mruby/lib/mruby-core-ext.rb
third-party/mruby/lib/mruby/build.rb
third-party/mruby/lib/mruby/build/command.rb
third-party/mruby/lib/mruby/build/load_gems.rb
third-party/mruby/lib/mruby/gem.rb
third-party/mruby/lib/mruby/lockfile.rb [new file with mode: 0644]
third-party/mruby/lib/mruby/source.rb
third-party/mruby/minirake
third-party/mruby/mrbgems/default.gembox
third-party/mruby/mrbgems/mruby-array-ext/mrbgem.rake
third-party/mruby/mrbgems/mruby-array-ext/mrblib/array.rb
third-party/mruby/mrbgems/mruby-array-ext/src/array.c
third-party/mruby/mrbgems/mruby-array-ext/test/array.rb
third-party/mruby/mrbgems/mruby-bin-config/mrbgem.rake
third-party/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb
third-party/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c
third-party/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c
third-party/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c
third-party/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c
third-party/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h
third-party/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h
third-party/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
third-party/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c
third-party/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb
third-party/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake
third-party/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
third-party/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c
third-party/mruby/mrbgems/mruby-class-ext/src/class.c
third-party/mruby/mrbgems/mruby-compiler/core/codegen.c
third-party/mruby/mrbgems/mruby-compiler/core/keywords
third-party/mruby/mrbgems/mruby-compiler/core/lex.def
third-party/mruby/mrbgems/mruby-compiler/core/node.h
third-party/mruby/mrbgems/mruby-compiler/core/parse.y
third-party/mruby/mrbgems/mruby-compiler/core/y.tab.c [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-compiler/mrbgem.rake
third-party/mruby/mrbgems/mruby-complex/mrbgem.rake [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-complex/mrblib/complex.rb [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-complex/src/complex.c [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-complex/test/complex.rb [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-enum-chain/mrblib/chain.rb
third-party/mruby/mrbgems/mruby-enum-chain/test/enum_chain.rb
third-party/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb
third-party/mruby/mrbgems/mruby-enum-ext/test/enum.rb
third-party/mruby/mrbgems/mruby-enumerator/mrbgem.rake
third-party/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb
third-party/mruby/mrbgems/mruby-enumerator/test/enumerator.rb
third-party/mruby/mrbgems/mruby-error/src/exception.c
third-party/mruby/mrbgems/mruby-eval/src/eval.c
third-party/mruby/mrbgems/mruby-eval/test/eval.rb
third-party/mruby/mrbgems/mruby-exit/src/mruby-exit.c
third-party/mruby/mrbgems/mruby-fiber/src/fiber.c
third-party/mruby/mrbgems/mruby-fiber/test/fiber.rb
third-party/mruby/mrbgems/mruby-hash-ext/mrbgem.rake
third-party/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb
third-party/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c
third-party/mruby/mrbgems/mruby-hash-ext/test/hash.rb
third-party/mruby/mrbgems/mruby-inline-struct/test/inline.c
third-party/mruby/mrbgems/mruby-io/.gitignore [deleted file]
third-party/mruby/mrbgems/mruby-io/.travis.yml [deleted file]
third-party/mruby/mrbgems/mruby-io/README.md
third-party/mruby/mrbgems/mruby-io/include/mruby/ext/io.h
third-party/mruby/mrbgems/mruby-io/mrbgem.rake
third-party/mruby/mrbgems/mruby-io/mrblib/file.rb
third-party/mruby/mrbgems/mruby-io/mrblib/file_constants.rb
third-party/mruby/mrbgems/mruby-io/mrblib/io.rb
third-party/mruby/mrbgems/mruby-io/mrblib/kernel.rb
third-party/mruby/mrbgems/mruby-io/run_test.rb [deleted file]
third-party/mruby/mrbgems/mruby-io/src/file.c
third-party/mruby/mrbgems/mruby-io/src/file_test.c
third-party/mruby/mrbgems/mruby-io/src/io.c
third-party/mruby/mrbgems/mruby-io/test/file.rb
third-party/mruby/mrbgems/mruby-io/test/file_test.rb
third-party/mruby/mrbgems/mruby-io/test/io.rb
third-party/mruby/mrbgems/mruby-io/test/mruby_io_test.c
third-party/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake
third-party/mruby/mrbgems/mruby-kernel-ext/mrblib/kernel.rb [deleted file]
third-party/mruby/mrbgems/mruby-kernel-ext/src/kernel.c
third-party/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb
third-party/mruby/mrbgems/mruby-math/src/math.c
third-party/mruby/mrbgems/mruby-math/test/math.rb
third-party/mruby/mrbgems/mruby-metaprog/src/metaprog.c
third-party/mruby/mrbgems/mruby-metaprog/test/metaprog.rb
third-party/mruby/mrbgems/mruby-method/mrblib/method.rb
third-party/mruby/mrbgems/mruby-method/mrblib/unbound_method.rb [deleted file]
third-party/mruby/mrbgems/mruby-method/src/method.c
third-party/mruby/mrbgems/mruby-method/test/method.rb
third-party/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb
third-party/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c
third-party/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb
third-party/mruby/mrbgems/mruby-object-ext/mrbgem.rake
third-party/mruby/mrbgems/mruby-object-ext/mrblib/object.rb
third-party/mruby/mrbgems/mruby-object-ext/src/object.c
third-party/mruby/mrbgems/mruby-object-ext/test/nil.rb
third-party/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c
third-party/mruby/mrbgems/mruby-objectspace/test/objectspace.rb
third-party/mruby/mrbgems/mruby-pack/.gitignore [deleted file]
third-party/mruby/mrbgems/mruby-pack/.travis.yml [deleted file]
third-party/mruby/mrbgems/mruby-pack/README.md
third-party/mruby/mrbgems/mruby-pack/mrbgem.rake
third-party/mruby/mrbgems/mruby-pack/packtest.rb [deleted file]
third-party/mruby/mrbgems/mruby-pack/run_test.rb [deleted file]
third-party/mruby/mrbgems/mruby-pack/src/pack.c
third-party/mruby/mrbgems/mruby-pack/test/pack.rb
third-party/mruby/mrbgems/mruby-print/mrblib/print.rb
third-party/mruby/mrbgems/mruby-print/src/print.c
third-party/mruby/mrbgems/mruby-proc-ext/src/proc.c
third-party/mruby/mrbgems/mruby-proc-ext/test/proc.rb
third-party/mruby/mrbgems/mruby-random/src/mt19937ar.c [deleted file]
third-party/mruby/mrbgems/mruby-random/src/mt19937ar.h [deleted file]
third-party/mruby/mrbgems/mruby-random/src/random.c
third-party/mruby/mrbgems/mruby-random/src/random.h [deleted file]
third-party/mruby/mrbgems/mruby-random/test/random.rb
third-party/mruby/mrbgems/mruby-range-ext/mrblib/range.rb
third-party/mruby/mrbgems/mruby-range-ext/src/range.c
third-party/mruby/mrbgems/mruby-range-ext/test/range.rb
third-party/mruby/mrbgems/mruby-rational/mrbgem.rake [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-rational/mrblib/rational.rb [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-rational/src/rational.c [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-rational/test/rational.rb [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-sleep/.gitignore [deleted file]
third-party/mruby/mrbgems/mruby-sleep/.travis.yml [deleted file]
third-party/mruby/mrbgems/mruby-sleep/.travis_build_config.rb [deleted file]
third-party/mruby/mrbgems/mruby-sleep/Rakefile [deleted file]
third-party/mruby/mrbgems/mruby-sleep/mrbgem.rake
third-party/mruby/mrbgems/mruby-sleep/src/mrb_sleep.c
third-party/mruby/mrbgems/mruby-socket/.travis.yml [deleted file]
third-party/mruby/mrbgems/mruby-socket/README.md
third-party/mruby/mrbgems/mruby-socket/mrbgem.rake
third-party/mruby/mrbgems/mruby-socket/run_test.rb [deleted file]
third-party/mruby/mrbgems/mruby-socket/src/socket.c
third-party/mruby/mrbgems/mruby-socket/test/sockettest.c
third-party/mruby/mrbgems/mruby-sprintf/src/kernel.c
third-party/mruby/mrbgems/mruby-sprintf/src/sprintf.c
third-party/mruby/mrbgems/mruby-sprintf/test/sprintf.rb
third-party/mruby/mrbgems/mruby-string-ext/mrbgem.rake
third-party/mruby/mrbgems/mruby-string-ext/mrblib/string.rb
third-party/mruby/mrbgems/mruby-string-ext/src/string.c
third-party/mruby/mrbgems/mruby-string-ext/test/numeric.rb [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-string-ext/test/range.rb [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-string-ext/test/string.rb
third-party/mruby/mrbgems/mruby-struct/mrblib/struct.rb
third-party/mruby/mrbgems/mruby-struct/src/struct.c
third-party/mruby/mrbgems/mruby-struct/test/struct.rb
third-party/mruby/mrbgems/mruby-symbol-ext/src/symbol.c
third-party/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb
third-party/mruby/mrbgems/mruby-test/driver.c
third-party/mruby/mrbgems/mruby-test/mrbgem.rake
third-party/mruby/mrbgems/mruby-test/vformat.c [new file with mode: 0644]
third-party/mruby/mrbgems/mruby-time/include/mruby/time.h
third-party/mruby/mrbgems/mruby-time/src/time.c
third-party/mruby/mrbgems/mruby-time/test/time.rb
third-party/mruby/mrblib/00class.rb
third-party/mruby/mrblib/array.rb
third-party/mruby/mrblib/enum.rb
third-party/mruby/mrblib/hash.rb
third-party/mruby/mrblib/kernel.rb
third-party/mruby/mrblib/mrblib.rake
third-party/mruby/mrblib/numeric.rb
third-party/mruby/mrblib/range.rb
third-party/mruby/mrblib/string.rb
third-party/mruby/mruby-source.gemspec
third-party/mruby/oss-fuzz/config/mruby.dict [new file with mode: 0644]
third-party/mruby/oss-fuzz/config/mruby_fuzzer.options [new file with mode: 0644]
third-party/mruby/oss-fuzz/config/mruby_proto_fuzzer.options [new file with mode: 0644]
third-party/mruby/oss-fuzz/mruby_fuzzer.c [new file with mode: 0644]
third-party/mruby/oss-fuzz/mruby_proto_fuzzer.cpp [new file with mode: 0644]
third-party/mruby/oss-fuzz/proto_to_ruby.cpp [new file with mode: 0644]
third-party/mruby/oss-fuzz/proto_to_ruby.h [new file with mode: 0644]
third-party/mruby/oss-fuzz/ruby.proto [new file with mode: 0644]
third-party/mruby/src/array.c
third-party/mruby/src/backtrace.c
third-party/mruby/src/class.c
third-party/mruby/src/codedump.c
third-party/mruby/src/debug.c
third-party/mruby/src/dump.c
third-party/mruby/src/enum.c
third-party/mruby/src/error.c
third-party/mruby/src/etc.c
third-party/mruby/src/fmt_fp.c
third-party/mruby/src/gc.c
third-party/mruby/src/hash.c
third-party/mruby/src/kernel.c
third-party/mruby/src/load.c
third-party/mruby/src/numeric.c
third-party/mruby/src/object.c
third-party/mruby/src/pool.c
third-party/mruby/src/print.c
third-party/mruby/src/proc.c
third-party/mruby/src/range.c
third-party/mruby/src/state.c
third-party/mruby/src/string.c
third-party/mruby/src/symbol.c
third-party/mruby/src/variable.c
third-party/mruby/src/vm.c
third-party/mruby/tasks/doc.rake [new file with mode: 0644]
third-party/mruby/tasks/gitlab.rake
third-party/mruby/tasks/libmruby.rake
third-party/mruby/tasks/mrbgems.rake
third-party/mruby/tasks/toolchains/android.rake
third-party/mruby/tasks/toolchains/clang.rake
third-party/mruby/tasks/toolchains/gcc.rake
third-party/mruby/tasks/toolchains/openwrt.rake
third-party/mruby/tasks/toolchains/visualcpp.rake
third-party/mruby/test/assert.rb
third-party/mruby/test/t/array.rb
third-party/mruby/test/t/class.rb
third-party/mruby/test/t/ensure.rb
third-party/mruby/test/t/enumerable.rb
third-party/mruby/test/t/exception.rb
third-party/mruby/test/t/float.rb
third-party/mruby/test/t/hash.rb
third-party/mruby/test/t/integer.rb
third-party/mruby/test/t/kernel.rb
third-party/mruby/test/t/module.rb
third-party/mruby/test/t/numeric.rb
third-party/mruby/test/t/range.rb
third-party/mruby/test/t/string.rb
third-party/mruby/test/t/syntax.rb
third-party/mruby/test/t/vformat.rb [new file with mode: 0644]
third-party/mruby/travis_config.rb

diff --git a/AUTHORS b/AUTHORS
index 4536741..a7a9151 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -19,6 +19,7 @@ Alek Storm
 Alex Nalivko
 Alexandros Konstantinakis-Karmis
 Alexis La Goutte
+Amir Livneh
 Amir Pakdel
 Anders Bakken
 Andreas Pohl
@@ -27,17 +28,20 @@ Andy Davies
 Angus Gratton
 Anna Henningsen
 Ant Bryan
+Asra Ali
 Benedikt Christoph Wolters
 Benjamin Peterson
 Bernard Spil
 Brendan Heinonen
 Brian Card
 Brian Suh
+Daniel Bevenius
 Daniel Evers
 Daniel Stenberg
 Dave Reisner
 David Beitey
 David Weekly
+Dmitri Tikhonov
 Dmitriy Vetutnev
 Don
 Dylan Plecki
@@ -47,9 +51,12 @@ Fabian Wiesel
 Gabi Davar
 Gaël PORTAY
 Geoff Hill
+George Liu
 Gitai
 Google Inc.
+Hajime Fujita
 Jacky Tian
+Jacky_Yin
 Jacob Champion
 James M Snell
 Jan Kundrát
@@ -69,11 +76,13 @@ Kit Chan
 Kyle Schomp
 LazyHamster
 Leo Neat
+Lorenz Nickel
 Lucas Pardue
 MATSUMOTO Ryosuke
 Marc Bachmann
 Matt Rudary
 Matt Way
+Michael Kaufmann
 Mike Conlen
 Mike Frysinger
 Mike Lothian
@@ -104,6 +113,7 @@ Tatsuhiko Kubo
 Tatsuhiro Tsujikawa
 Tobias Geerinckx-Rice
 Tom Harwood
+Tomas Krizek
 Tomasz Buchert
 Tomasz Torcz
 Vernon Tang
@@ -124,6 +134,7 @@ es
 fangdingjun
 jwchoi
 kumagi
+lhuang04
 lstefani
 makovich
 mod-h2-dev
index 69c2c7b..bfcd07d 100644 (file)
 
 cmake_minimum_required(VERSION 3.0)
 # XXX using 1.8.90 instead of 1.9.0-DEV
-project(nghttp2 VERSION 1.41.0)
+project(nghttp2 VERSION 1.46.0)
 
 # See versioning rule:
-#  http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
-set(LT_CURRENT  34)
-set(LT_REVISION 0)
-set(LT_AGE      20)
+#  https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+set(LT_CURRENT  35)
+set(LT_REVISION 1)
+set(LT_AGE      21)
 
 set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
 include(Version)
@@ -61,6 +61,13 @@ find_package(OpenSSL 1.0.1)
 find_package(Libev 4.11)
 find_package(Libcares 1.7.5)
 find_package(ZLIB 1.2.3)
+find_package(Libngtcp2 0.0.0)
+find_package(Libngtcp2_crypto_openssl 0.0.0)
+if(LIBNGTCP2_CRYPTO_OPENSSL_FOUND)
+  set(HAVE_LIBNGTCP2_CRYPTO_OPENSSL 1)
+endif()
+find_package(Libnghttp3 0.0.0)
+find_package(Libbpf 0.4.0)
 if(OPENSSL_FOUND AND LIBEV_FOUND AND ZLIB_FOUND)
   set(ENABLE_APP_DEFAULT ON)
 else()
@@ -84,8 +91,6 @@ find_package(LibXml2 2.6.26)
 set(WITH_LIBXML2_DEFAULT    ${LIBXML2_FOUND})
 find_package(Jemalloc)
 set(WITH_JEMALLOC_DEFAULT   ${JEMALLOC_FOUND})
-find_package(Spdylay 1.3.2)
-set(WITH_SPDYLAY_DEFAULT    ${SPDYLAY_FOUND})
 
 include(CMakeOptions.txt)
 
@@ -184,9 +189,18 @@ if(HAVE_CUNIT)
 endif()
 
 # openssl (for src)
+include(CheckSymbolExists)
 set(HAVE_OPENSSL    ${OPENSSL_FOUND})
 if(OPENSSL_FOUND)
   set(OPENSSL_INCLUDE_DIRS  ${OPENSSL_INCLUDE_DIR})
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_INCLUDES   "${OPENSSL_INCLUDE_DIR}")
+  set(CMAKE_REQUIRED_LIBRARIES  "${OPENSSL_LIBRARIES}")
+  check_symbol_exists(SSL_is_quic "openssl/ssl.h" HAVE_SSL_IS_QUIC)
+  if(NOT HAVE_SSL_IS_QUIC)
+    message(WARNING "OpenSSL in ${OPENSSL_LIBRARIES} dose not have SSL_is_quic.  HTTP/3 support cannot be enabled")
+  endif()
+  cmake_pop_check_state()
 else()
   set(OPENSSL_INCLUDE_DIRS  "")
   set(OPENSSL_LIBRARIES     "")
@@ -220,18 +234,36 @@ else()
 endif()
 # jemalloc
 set(HAVE_JEMALLOC   ${JEMALLOC_FOUND})
-# spdylay (for src/nghttpx and src/h2load)
-set(HAVE_SPDYLAY    ${SPDYLAY_FOUND})
 
 if(ENABLE_ASIO_LIB)
   find_package(Boost 1.54.0 REQUIRED system thread)
 endif()
 
+# libbpf (for bpf)
+set(HAVE_LIBBPF ${LIBBPF_FOUND})
+if(LIBBPF_FOUND)
+  set(BPFCFLAGS -Wall -O2 -g)
+  if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    # For Debian/Ubuntu
+    set(EXTRABPFCFLAGS -I/usr/include/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu)
+  endif()
+
+  check_c_source_compiles("
+#include <linux/bpf.h>
+int main() { enum bpf_stats_type foo; (void)foo; }" HAVE_BPF_STATS_TYPE)
+endif()
+
 # The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL and libev
 if(ENABLE_APP AND NOT (ZLIB_FOUND AND OPENSSL_FOUND AND LIBEV_FOUND))
   message(FATAL_ERROR "Applications were requested (ENABLE_APP=1) but dependencies are not met.")
 endif()
 
+# HTTP/3 requires quictls/openssl, libngtcp2, libngtcp2_crypto_openssl
+# and libnghttp3.
+if(ENABLE_HTTP3 AND NOT (HAVE_SSL_IS_QUIC AND LIBNGTCP2_FOUND AND LIBNGTCP2_CRYPTO_OPENSSL_FOUND AND LIBNGHTTP3_FOUND))
+  message(FATAL_ERROR "HTTP/3 was requested (ENABLE_HTTP3=1) but dependencies are not met.")
+endif()
+
 # HPACK tools requires jansson
 if(ENABLE_HPACK_TOOLS AND NOT HAVE_JANSSON)
   message(FATAL_ERROR "HPACK tools were requested (ENABLE_HPACK_TOOLS=1) but dependencies are not met.")
@@ -452,11 +484,16 @@ foreach(name
   configure_file("${name}.in" "${name}" @ONLY)
 endforeach()
 
+if(APPLE)
+  add_definitions(-D__APPLE_USE_RFC_3542)
+endif()
+
 include_directories(
   "${CMAKE_CURRENT_BINARY_DIR}" # for config.h
 )
 # For use in src/CMakeLists.txt
 set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}")
+set(PKGLIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}/${CMAKE_PROJECT_NAME}")
 
 install(FILES README.rst DESTINATION "${CMAKE_INSTALL_DOCDIR}")
 
@@ -473,6 +510,7 @@ add_subdirectory(integration-tests)
 add_subdirectory(doc)
 add_subdirectory(contrib)
 add_subdirectory(script)
+add_subdirectory(bpf)
 
 
 string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type)
@@ -503,8 +541,11 @@ message(STATUS "summary of build options:
       Libxml2:        ${HAVE_LIBXML2} (LIBS='${LIBXML2_LIBRARIES}')
       Libev:          ${HAVE_LIBEV} (LIBS='${LIBEV_LIBRARIES}')
       Libc-ares:      ${HAVE_LIBCARES} (LIBS='${LIBCARES_LIBRARIES}')
+      Libngtcp2:      ${HAVE_LIBNGTCP2} (LIBS='${LIBNGTCP2_LIBRARIES}')
+      Libngtcp2_crypto_openssl: ${HAVE_LIBNGTCP2_CRYPTO_OPENSSL} (LIBS='${LIBNGTCP2_CRYPTO_OPENSSL_LIBRARIES}')
+      Libnghttp3:     ${HAVE_LIBNGHTTP3} (LIBS='${LIBNGHTTP3_LIBRARIES}')
+      Libbpf:         ${HAVE_LIBBPF} (LIBS='${LIBBPF_LIBRARIES}')
       Libevent(SSL):  ${HAVE_LIBEVENT_OPENSSL} (LIBS='${LIBEVENT_OPENSSL_LIBRARIES}')
-      Spdylay:        ${HAVE_SPDYLAY} (LIBS='${SPDYLAY_LIBRARIES}')
       Jansson:        ${HAVE_JANSSON} (LIBS='${JANSSON_LIBRARIES}')
       Jemalloc:       ${HAVE_JEMALLOC} (LIBS='${JEMALLOC_LIBRARIES}')
       Zlib:           ${HAVE_ZLIB} (LIBS='${ZLIB_LIBRARIES}')
@@ -522,6 +563,7 @@ message(STATUS "summary of build options:
       Examples:       ${ENABLE_EXAMPLES}
       Python bindings:${ENABLE_PYTHON_BINDINGS}
       Threading:      ${ENABLE_THREADS}
+      HTTP/3(EXPERIMENTAL): ${ENABLE_HTTP3}
 ")
 if(ENABLE_LIB_ONLY_DISABLED_OTHERS)
   message("Only the library will be built. To build other components "
index a8332bf..754428a 100644 (file)
@@ -17,6 +17,7 @@ option(ENABLE_LIB_ONLY  "Build libnghttp2 only.  This is a short hand for -DENAB
 option(ENABLE_STATIC_LIB "Build libnghttp2 in static mode also")
 option(ENABLE_SHARED_LIB "Build libnghttp2 as a shared library" ON)
 option(ENABLE_STATIC_CRT "Build libnghttp2 against the MS LIBCMT[d]")
+option(ENABLE_HTTP3      "Enable HTTP/3 support" OFF)
 
 option(WITH_LIBXML2     "Use libxml2"
   ${WITH_LIBXML2_DEFAULT})
index 3e04f08..cffe1d6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-commit 8f7b008b158e12de0e58247afd170f127dbb6456 (HEAD, tag: v1.41.0, origin/master, origin/HEAD, master)
+commit 7af0c508be9cbec407268e2f546f597d268c104e (HEAD, tag: v1.46.0, origin/master, origin/HEAD, master)
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-06-02
+AuthorDate: 2021-10-19
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-06-02
+CommitDate: 2021-10-19
+
+    Update manual pages
+
+commit f8474b25f02c4faa6d4250800a164227cf89b327
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-18
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-18
+
+    nghttpx: Reduce dgram size if sendmsg fails with EINVAL or EMSGSIZE
+
+commit 15a8d913ead5dff164ff0a4191b600b78eec1baf
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-17
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-17
+
+    examples/client: Enable ALPN
+
+commit 65d3c9047f5a254a7690178b514655d7b7d7f6f6
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-17
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-17
+
+    Replace TLSv23_method with TLS_method
+
+commit 8c36971ea9679f1e7b05a4a3e6db654a6d9d9019
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-17
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-17
+
+    Compile with OPENSSL_NO_DEPRECATED and fix memory leaks
+
+commit ba1dff187b902f2d09b184b66fc278501eb4656e
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-17
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-17
 
     Update bash_completion
 
-commit 83086ba91a20a444a3b151bd5e0f55037795a31a
+commit 8ecacc8ed290353cd4414d6a1e70757b0a0c6309
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-06-02
+AuthorDate: 2021-10-17
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-06-02
+CommitDate: 2021-10-17
 
     Update manual pages
 
-commit c3b46625633cd9a4519f6fbcd9048127b84a5514
-Merge: 3eecc2ca f8da73bd
-Author:     Tatsuhiro Tsujikawa <404610+tatsuhiro-t@users.noreply.github.com>
-AuthorDate: 2020-06-02
-Commit:     GitHub <noreply@github.com>
-CommitDate: 2020-06-02
+commit 9d418966633a07ac7339ac50569e40c9f8d17d58
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-17
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-17
 
-    Merge pull request from GHSA-q5wr-xfw9-q7xr
-    
-    Implement max settings option
+    nghttpx: Rename --frontend-quic-server-id to --quic-server-id
 
-commit 3eecc2ca45530024abb687bf808ec768eaa5e98a
+commit 18d4a9e4ff5442b1108f9f07e307539ca2fa3a85
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-06-02
+AuthorDate: 2021-10-17
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-06-02
+CommitDate: 2021-10-17
 
-    Bump version number to v1.41.0, LT revision to 34:0:20
+    Update bash_completion
 
-commit 881c060d8c92c5246d9a6b5829e63838869bbaa9
+commit 1745a306442a8811e3c0baa48c9953fdeab8abf4
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-06-02
+AuthorDate: 2021-10-17
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-06-02
+CommitDate: 2021-10-17
 
-    Update AUTHORS
+    Update manual pages
 
-commit f8da73bd042f810f34d19f9eae02b46d870af394
-Author:     James M Snell <jasnell@gmail.com>
-AuthorDate: 2020-04-19
-Commit:     James M Snell <jasnell@gmail.com>
-CommitDate: 2020-05-05
+commit 0cc7c598ff8ac21222c4f6d7840ce441444a9056
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-17
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-17
 
-    Earlier check for settings flood
+    src: TLS_DEFAULT_CIPHERSUITES was deprecated in OpenSSL 3.0.0
 
-commit 336a98feb0d56b9ac54e12736b18785c27f75090
-Author:     James M Snell <jasnell@gmail.com>
-AuthorDate: 2020-04-17
-Commit:     James M Snell <jasnell@gmail.com>
-CommitDate: 2020-05-05
+commit 8c4fbb86d81d9ba8226e2e41d2e247cd1aa62c36
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-17
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-17
 
-    Implement max settings option
+    Bump version number to 1.46.0, LT revision to 35:1:21
 
-commit ef41583614e95efd12b6cce821e34837c1b28ed0
+commit 693431312c7b425d4aec0ae0887e331b075571f7
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-04-22
+AuthorDate: 2021-10-15
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-04-22
+CommitDate: 2021-10-15
 
-    Revert "Add missing connection error handling"
-    
-    This reverts commit b7d16101413276884d7f51c64f989f5f61abecb8.
+    Fix cmake build
 
-commit 979e6c5325826d06922f25047ffafb7ed92fa749
-Merge: b7d16101 c663349f
-Author:     Tatsuhiro Tsujikawa <404610+tatsuhiro-t@users.noreply.github.com>
-AuthorDate: 2020-04-21
-Commit:     GitHub <noreply@github.com>
-CommitDate: 2020-04-21
+commit f3fca2a19a95d67a2cdcaec6e1b72ccdc9cfafe0
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-15
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-15
 
-    Merge pull request #1459 from nghttp2/proxyprotov2
-    
-    nghttpx: Add PROXY protocol version 2
+    Update doc
 
-commit b7d16101413276884d7f51c64f989f5f61abecb8
+commit 1ce9efc64479ad5854aab00ebc2e317f878a421e
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-04-21
+AuthorDate: 2021-10-15
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-04-21
+CommitDate: 2021-10-15
 
-    Add missing connection error handling
+    nghttpx: Set SCT data when built with boringssl
 
-commit cd53bd81bfbf571a0f7836b5979e19702a76890f
-Merge: 3b17a659 e5625b8c
-Author:     Tatsuhiro Tsujikawa <404610+tatsuhiro-t@users.noreply.github.com>
-AuthorDate: 2020-04-18
-Commit:     GitHub <noreply@github.com>
-CommitDate: 2020-04-18
+commit 7055501efd26a9b64d7d46206ded82af8d1ea2b8
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-15
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-15
 
-    Merge pull request #1460 from gportay/patch-1
-    
-    Fix doc
+    src: Enable HTTP/3 with boringssl
 
-commit e5625b8cf083b076c0fcb9d4b80749f30c75b4f7
-Author:     Gaël PORTAY <gael.portay@gmail.com>
-AuthorDate: 2020-04-18
-Commit:     GitHub <noreply@github.com>
-CommitDate: 2020-04-18
+commit c790ee64a46d6f58fc034b719c3c7808d0473a9c
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-15
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-15
 
-    Fix doc
+    src: Prefer #ifdef for a single condition
 
-commit c663349f24b851865f4f1f5ca21de542a2e5c07f
+commit 9fb05d5ea258ac5707b852a856608b00193169d3
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-04-18
+AuthorDate: 2021-10-15
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-04-18
+CommitDate: 2021-10-15
 
-    integration: Add PROXY protocol v2 tests
+    Fix compile error under mac os
 
-commit 854e9fe395e928d31650a0f398897cc209064c90
+commit 3742acaf398d394a84e70f25894f17f86f8a1745
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-04-18
+AuthorDate: 2021-10-15
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-04-18
+CommitDate: 2021-10-15
 
-    nghttpx: Always call init_forwarded_for
-    
-    Always call init_forwarded_for to get the default when source address
-    in PROXY protocol is ignored.  This ensures that forwarded header
-    field has the same value as x-forwarded-for.
+    nghttpx: Fix wrong SSL_CTX object usage
 
-commit c60ea227cc61294da0ea0355108c2f90d77f974a
+commit d8282de2290a265956dee94bfe068d2cca36747d
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-04-18
+AuthorDate: 2021-10-15
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-04-18
+CommitDate: 2021-10-15
+
+    nghttpx: Respect !tls-no-postpone-early-data with boringssl
+
+commit 3a721a9dd510f607ca6f7d57efa8bfa467fa1b33
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-14
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-15
+
+    nghttpx: Send session ticket after handshake with boringssl
+
+commit 0b6092446b42cff5d3311a47bdb2185c647a71ea
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-14
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-14
+
+    src: Compile with boringssl for non-http3 build
+
+commit fa7a916ef3b6e518d7a65e6256a9ebab1bab83ce
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-10
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-10
+
+    nghttpx: Store initial_rtt in ev_tstamp for consistency
+
+commit 69c41871002c2ab9ac3fd4b7d720b2dda1197ec6
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-10
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-10
+
+    nghttpx: Add --frontend-quic-initial-rtt option
+
+commit 07128719c4048c0c478ea073d6a850105153ab79
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-10
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-10
+
+    Workaround broken version check in AX_PYTHON_DEVEL
+
+commit 7471fa627d4992112910b0d6f068ea966992095f
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-10
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-10
+
+    Update ax_python_devel.m4
+
+commit d7af5924ff749df7887144f395f954338da0cbdd
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-10
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-10
+
+    nghttpx: Extend QUIC server ID to 4 bytes
+
+commit a48e9d3d80c2c919286eac104d8df97e550bd7ca
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-06
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-06
+
+    Add bpf to clang-format
+
+commit 474a6db00c16a68463d39910c2a65a71041da0cb
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-06
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-06
+
+    Compile with gcc
+
+commit cb6aea9aa932b76fd0a57d7ace711c66c5d280f5
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-06
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-06
+
+    Compile with -DNDEBUG
+
+commit f4290c649761d42d17a5b09e7280d5b4c6229dd0
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-04
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-04
+
+    Fix compile error
+
+commit 086b85b8f971b372dc061ad52966a2d92804369a
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-04
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-04
+
+    nghttpx: Unload BPF program after setting up all QUIC listeners
+
+commit abee658a60806b5c96d5563ae9f5a06f90610725
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-02
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-02
+
+    nghttpx: Make sure that ngtcp2_conn_update_pkt_tx_time is called
+
+commit 87bdc2166768bde482644cdf0ac139d0869fc45a
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-10-02
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-10-02
+
+    nghttpx: Add --worker-process-grace-shutdown-period option
+
+commit 3e25ee818178eea37950f0825242f1c1465e55e8
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-29
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-29
+
+    256k memlock is not enough when reloading happens
+
+commit 0266c458a34d5ef7455cffe3bf34ec9b25db99c2
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-29
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-29
+
+    nghttpx: Add --max-worker-processes option
+
+commit d9c7631dcbf9651f7b9d7837a7c7ea1d82658ee6
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-29
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-29
+
+    Fix compile error
+
+commit df064fa2ba60d237b8f708eebe9ef6e762d06055
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-29
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-29
+
+    nghttpx: Unload BPF objects on reload to avoid running out of memlock
+
+commit 318e0c8447e2399e7c1e95d8ae8d00118ccea5f7
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-28
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-28
+
+    Guard msghdr_get_local_addr with ENABLE_HTTP3 macro
+
+commit 17d5503bf244fe484cd0332158d6dac21c9487b5
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-28
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-28
 
     Update doc
 
-commit 49cd8e6e733a74d52d442a3d2667fd130d6437c8
+commit 19b4da64016f979b38a1d8eea127b153c2d22060
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-04-17
+AuthorDate: 2021-09-26
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-04-18
+CommitDate: 2021-09-26
 
-    nghttpx: Add PROXY-protocol v2 support
+    nghttpx: Support h3-29
 
-commit 3b17a659f69fb2ef5d2239142437da2902e61911
-Merge: 600fcdf5 dc7a7df6
-Author:     Tatsuhiro Tsujikawa <404610+tatsuhiro-t@users.noreply.github.com>
-AuthorDate: 2020-03-31
-Commit:     GitHub <noreply@github.com>
-CommitDate: 2020-03-31
+commit 886dc93f182aa7ab6570c77013f35494889a2269
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-26
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-26
 
-    Merge pull request #1453 from Leo-Neat/master
-    
-    Add CIFuzz
+    nghttpx: Fail h3 connection attempt if no ALPN is negotiated
 
-commit 600fcdf52d60f67ecd936d61eaf0c7ecb8624075
-Merge: b3f85e2d 4922bb41
-Author:     Tatsuhiro Tsujikawa <404610+tatsuhiro-t@users.noreply.github.com>
-AuthorDate: 2020-03-31
-Commit:     GitHub <noreply@github.com>
-CommitDate: 2020-03-31
+commit 407df2822e4b989c53c04b4f7902d2a9210ad506
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-26
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-26
 
-    Merge pull request #1455 from xjtian/long_serials
+    Remove check for UDP_SEGMENT
     
-    Fix get_x509_serial for long serial numbers
+    Check for UDP_SEGMENT is for debian 10, but now that we have debian
+    11, remove the check because it breaks cross-build.
 
-commit 4922bb41d604a15483e12f1b33bac2bf6628d866
-Author:     Jacky Tian <xjtian@fb.com>
-AuthorDate: 2020-03-31
-Commit:     Jacky Tian <xjtian@fb.com>
-CommitDate: 2020-03-31
+commit f6da0d342acc123ce0575146c4ab17f8b7e3146e
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-24
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-24
 
-    static_cast size parameter in StringRef constructor to size_t
+    nghttpx: Fix crash if no keying materials are specified in file
 
-commit aad8697575d90b1763c31ad06986be0550917aac
-Author:     Jacky Tian <xjtian@fb.com>
-AuthorDate: 2020-03-30
-Commit:     Jacky Tian <xjtian@fb.com>
-CommitDate: 2020-03-31
+commit 7271537a1531bad7ca0e2153b1cf188b6462dda4
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-24
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-24
 
-    Fix get_x509_serial for long serial numbers
+    nghttpx: Add --rlimit-memlock option
 
-commit dc7a7df61c7cd1cc05c9c09f827e564495c2bebe
-Author:     Leo Neat <lneat@google.com>
-AuthorDate: 2020-03-18
-Commit:     Leo Neat <lneat@google.com>
-CommitDate: 2020-03-18
+commit d0e8efac4dd0411a8dab8ede6ec5e664f73c77a2
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-24
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-24
 
-    Adding CIFuzz
+    nghttpx: Fix bug that reading QUIC secret file fails without line separator
 
-commit b3f85e2daa629732ac3ebb092cd5543c26045e03
-Merge: ffb49c6c 2ec58551
-Author:     Tatsuhiro Tsujikawa <404610+tatsuhiro-t@users.noreply.github.com>
-AuthorDate: 2020-02-20
-Commit:     GitHub <noreply@github.com>
-CommitDate: 2020-02-20
+commit 27e6d56d83f9a0669ef901d5eac145fc2d6966af
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-23
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-23
 
-    Merge pull request #1444 from nghttp2/fix-recv-window-flow-control-issue
-    
-    Fix receiving stream data stall
+    Update doc
 
-commit ffb49c6c589617d6c9a4172464b9100b377e56f9
-Merge: 459df42b 866eadb5
-Author:     Tatsuhiro Tsujikawa <404610+tatsuhiro-t@users.noreply.github.com>
-AuthorDate: 2020-02-20
-Commit:     GitHub <noreply@github.com>
-CommitDate: 2020-02-20
+commit c5122c12cb760e52eb37768a39f1114e07954200
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-23
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-23
 
-    Merge pull request #1435 from geoffhill/master
-    
-    Enable session_create_idle_stream test, fix errors
+    Update bash_completion
 
-commit 2ec585518e83bec7de8deb0d429cd744d99fc72b
+commit 282050c596715ac6872b16fa6bdf9720647cffcd
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-02-19
+AuthorDate: 2021-09-23
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-02-20
+CommitDate: 2021-09-23
 
-    Fix receiving stream data stall
-    
-    Previously, if automatic window update is enabled (which is default),
-    after window size is set to 0 by
-    nghttp2_session_set_local_window_size, once the receiving window is
-    exhausted, even after window size is increased by
-    nghttp2_session_set_local_window_size, no more data cannot be
-    received.  This is because nghttp2_session_set_local_window_size does
-    not submit WINDOW_UPDATE.  It is only triggered when new data arrives
-    but since window is filled up, no more data cannot be received, thus
-    dead lock happens.
-    
-    This commit fixes this issue.  nghttp2_session_set_local_window_size
-    submits WINDOW_UPDATE if necessary.
-    
-    https://github.com/curl/curl/issues/4939
+    Update manual pages
 
-commit 459df42b8b074dffd40ac1f95fc65ad099050a7a
-Merge: 5e13274b a4c1fed5
-Author:     Tatsuhiro Tsujikawa <404610+tatsuhiro-t@users.noreply.github.com>
-AuthorDate: 2020-02-11
-Commit:     GitHub <noreply@github.com>
-CommitDate: 2020-02-11
+commit 308c73bfa2aa2e191d7a0bbbf2355ca7b2ef9b10
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-22
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-23
 
-    Merge pull request #1442 from nghttp2/upgrade-llhttp
+    nghttpx: Read QUIC keying materials from file
     
-    Bump llhttp to 2.0.4
+    Add --frontend-quic-secret-file to read QUIC keying materials from
+    file.  --frontend-quic-connection-id-encryption-key was removed in
+    favor of this new option.
 
-commit a4c1fed5139b2df7ce611a519a7b1d69aee3bae0
+commit c40309ae8e17d8cabb0b437fbfa3a24757a0cf46
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2020-02-11
+AuthorDate: 2021-09-22
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2020-02-11
+CommitDate: 2021-09-23
 
-    Bump llhttp to 2.0.4
+    nghttpx: optarg should be allocated per configuration
 
-commit 866eadb5de0f859d30272f5359a79c195271cd6c
-Author:     Geoff Hill <geoffhill@fb.com>
-AuthorDate: 2020-01-23
-Commit:     Geoff Hill <geoffhill@fb.com>
-CommitDate: 2020-01-23
+commit 1c7a4ecc7f7d1b289123a0575834eb00d16bd65f
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-21
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-21
 
-    Enable session_create_idle_stream test, fix errors
-    
-    Add the currently-unused `test_nghttp2_session_create_idle_stream()`
-    function to the test suite definition.
-    
-    Modify the test in two places to make it pass:
-    
-      * Use stream ID=10 as the priority stream ID to test automatic creation
-        of streams for priority specs. The code below checks against stream
-        ID=10 so I assume this was a typo in the test.
-    
-      * Set the `last_sent_stream_id` instead of the `next_stream_id` to test
-        that idle streams cannot be created with smaller numbers than the
-        most-recently-seen stream ID. Looking at the validation path in
-        `session_detect_idle_stream()`, I think this was another test typo.
+    nghttpx: Rename generate_encrypted_quic_connection_id to generate_quic_connection_id
+
+commit 80cc623eb2683299791b2988722ffcf0e6488d62
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-21
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-21
 
-commit 5e13274b7c533b00f2a14582de5f6b34c08b0018
+    nghttpx: Allocate server id in Connection ID
+
+commit 89457fd9915159c746e5503e5da58bee9fc2445e
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2019-12-21
+AuthorDate: 2021-09-21
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2019-12-21
+CommitDate: 2021-09-21
 
-    Fix typo
+    More https
 
-commit e0d7f7de5e58b2e9abd92ee3384f78e91d018503
+commit 257043b8fbe8be9ea53f1a72350a06489b255ba9
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2019-12-21
+AuthorDate: 2021-09-21
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2019-12-21
+CommitDate: 2021-09-21
 
-    h2load: Allow port in --connect-to
+    Fix issue that libev cannot be found with autotools under mac osx
 
-commit df575f968fa3d82fb40c2637e7d3e245def43766
-Author:     lucas <lucas@cloudflare.com>
-AuthorDate: 2019-12-12
+commit 657d94b99283f3ec810d87b05b5f7bbc1ca50768
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-21
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2019-12-21
+CommitDate: 2021-09-21
 
-    h2load: add --connect-to option
+    Fix compile error with libressl
 
-commit 1fff737955d3e080d4e4be9ecb615c83fd3fd767
+commit 06dc7d59641a91eaa7bad7ad3995311c87ec8eed
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2019-12-18
+AuthorDate: 2021-09-21
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2019-12-18
+CommitDate: 2021-09-21
 
-    clang-format-9
+    Make sure that nghttp2 can be built from tar archive
 
-commit b40c6c862fafe87fa32b28bf040456b064482893
-Merge: 2d5f7659 9bc2c75e
-Author:     Tatsuhiro Tsujikawa <404610+tatsuhiro-t@users.noreply.github.com>
-AuthorDate: 2019-12-08
-Commit:     GitHub <noreply@github.com>
-CommitDate: 2019-12-08
+commit b50079524b869be871c70e95264c82be7f864770
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-21
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-21
 
-    Merge pull request #1418 from vszakats/patch-1
-    
-    lib/CMakeLists.txt: Make hard-coded static lib suffix optional
+    Always include optional files to EXTRA_DIST
 
-commit 9bc2c75e388fbb5e6e694ef4471bd63521c966ae
-Author:     Viktor Szakats <vszakats@users.noreply.github.com>
-AuthorDate: 2019-11-15
-Commit:     Viktor Szakats <commit@vsz.me>
-CommitDate: 2019-11-15
+commit cdf1f269ff1336025a240a5db5cb3043d7db0249
+Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+AuthorDate: 2021-09-21
+Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+CommitDate: 2021-09-21
 
-    lib/CMakeLists.txt: Make hard-coded static lib suffix optional
-    
-    It can be set via the `STATIC_LIB_SUFFIX` variable.
-    
-    This fixes every existing dependent project that relied on the name
-    having no suffix and thus capable of using either a static or shared
-    flavour depending on which one is present on this or how the linker
-    is configured.
-    
-    Ref: https://github.com/nghttp2/nghttp2/pull/1394
+    Add missing cmake files to EXTRA_DIST
 
-commit 2d5f76594a8c4e11d6e2a70588c01433f214150b
+commit 738b562f398e46e3af242150a7f2c92eaa24741f
 Author:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-AuthorDate: 2019-11-15
+AuthorDate: 2021-09-20
 Commit:     Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
-CommitDate: 2019-11-15
+CommitDate: 2021-09-20
 
-    Bump up version number to 1.41.0-DEV
+    Bump up version number to 1.46.0-DEV
diff --git a/INSTALL b/INSTALL
index 8865734..e82fd21 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -1,8 +1,8 @@
 Installation Instructions
 *************************
 
-   Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
-Foundation, Inc.
+   Copyright (C) 1994-1996, 1999-2002, 2004-2017, 2020-2021 Free
+Software Foundation, Inc.
 
    Copying and distribution of this file, with or without modification,
 are permitted in any medium without royalty provided the copyright
@@ -225,7 +225,7 @@ order to use an ANSI C compiler:
 
 and if that doesn't work, install pre-built binaries of GCC for HP-UX.
 
-   HP-UX 'make' updates targets which have the same time stamps as their
+   HP-UX 'make' updates targets which have the same timestamps as their
 prerequisites, which makes it generally unusable when shipped generated
 files such as 'configure' are involved.  Use GNU 'make' instead.
 
index af0e185..79174a5 100644 (file)
@@ -20,7 +20,7 @@
 # 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.
-SUBDIRS = lib third-party src examples python tests integration-tests \
+SUBDIRS = lib third-party src bpf examples python tests integration-tests \
        doc contrib script
 
 # Now with python setuptools, make uninstall will leave many files we
@@ -37,7 +37,6 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
        cmakeconfig.h.in \
        CMakeLists.txt \
        CMakeOptions.txt \
-       cmake/FindSpdylay.cmake \
        cmake/ExtractValidFlags.cmake \
        cmake/FindJemalloc.cmake \
        cmake/FindLibev.cmake \
@@ -46,7 +45,12 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
        cmake/FindCython.cmake \
        cmake/FindLibevent.cmake \
        cmake/FindJansson.cmake \
-       cmake/FindLibcares.cmake
+       cmake/FindLibcares.cmake \
+       cmake/FindSystemd.cmake \
+       cmake/FindLibbpf.cmake \
+       cmake/FindLibnghttp3.cmake \
+       cmake/FindLibngtcp2.cmake \
+       cmake/FindLibngtcp2_crypto_openssl.cmake
 
 .PHONY: clang-format
 
@@ -58,4 +62,4 @@ clang-format:
        test -z $${CLANGFORMAT} && CLANGFORMAT="clang-format"; \
        $${CLANGFORMAT} -i lib/*.{c,h} lib/includes/nghttp2/*.h \
        src/*.{c,cc,h} src/includes/nghttp2/*.h examples/*.{c,cc} \
-       tests/*.{c,h}
+       tests/*.{c,h} bpf/*.c
index a1ac0b0..a89384d 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -190,8 +190,8 @@ am__recursive_targets = \
   $(am__extra_recursive_targets)
 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
        cscope distdir distdir-am dist dist-all distcheck
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
-       $(LISP)config.h.in
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
+       config.h.in
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
 # *not* preserved.
@@ -208,9 +208,6 @@ am__define_uniq_tagged_files = \
   unique=`for i in $$list; do \
     if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
   done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-CSCOPE = cscope
 DIST_SUBDIRS = $(SUBDIRS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
        $(top_srcdir)/lib/includes/nghttp2/nghttp2ver.h.in AUTHORS \
@@ -254,6 +251,8 @@ am__relativize = \
 DIST_ARCHIVES = $(distdir).tar.gz
 GZIP_ENV = --best
 DIST_TARGETS = dist-gzip
+# Exists only to be overridden by the user if desired.
+AM_DISTCHECK_DVI_TARGET = dvi
 distuninstallcheck_listfiles = find . -type f -print
 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
   | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
@@ -272,11 +271,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -295,8 +297,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -307,9 +312,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -318,9 +326,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -358,8 +375,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -446,7 +464,7 @@ top_srcdir = @top_srcdir@
 # 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.
-SUBDIRS = lib third-party src examples python tests integration-tests \
+SUBDIRS = lib third-party src bpf examples python tests integration-tests \
        doc contrib script
 
 
@@ -461,7 +479,6 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
        cmakeconfig.h.in \
        CMakeLists.txt \
        CMakeOptions.txt \
-       cmake/FindSpdylay.cmake \
        cmake/ExtractValidFlags.cmake \
        cmake/FindJemalloc.cmake \
        cmake/FindLibev.cmake \
@@ -470,7 +487,12 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
        cmake/FindCython.cmake \
        cmake/FindLibevent.cmake \
        cmake/FindJansson.cmake \
-       cmake/FindLibcares.cmake
+       cmake/FindLibcares.cmake \
+       cmake/FindSystemd.cmake \
+       cmake/FindLibbpf.cmake \
+       cmake/FindLibnghttp3.cmake \
+       cmake/FindLibngtcp2.cmake \
+       cmake/FindLibngtcp2_crypto_openssl.cmake
 
 all: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -662,7 +684,6 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
        -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -746,6 +767,10 @@ dist-xz: distdir
        tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
        $(am__post_remove_distdir)
 
+dist-zstd: distdir
+       tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
+       $(am__post_remove_distdir)
+
 dist-tarZ: distdir
        @echo WARNING: "Support for distribution archives compressed with" \
                       "legacy program 'compress' is deprecated." >&2
@@ -788,6 +813,8 @@ distcheck: dist
          eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
        *.zip*) \
          unzip $(distdir).zip ;;\
+       *.tar.zst*) \
+         zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
        esac
        chmod -R a-w $(distdir)
        chmod u+w $(distdir)
@@ -803,7 +830,7 @@ distcheck: dist
            $(DISTCHECK_CONFIGURE_FLAGS) \
            --srcdir=../.. --prefix="$$dc_install_base" \
          && $(MAKE) $(AM_MAKEFLAGS) \
-         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
          && $(MAKE) $(AM_MAKEFLAGS) check \
          && $(MAKE) $(AM_MAKEFLAGS) install \
          && $(MAKE) $(AM_MAKEFLAGS) installcheck \
@@ -968,18 +995,19 @@ uninstall-am: uninstall-dist_docDATA
        am--refresh check check-am clean clean-cscope clean-generic \
        clean-libtool cscope cscopelist-am ctags ctags-am dist \
        dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
-       dist-xz dist-zip distcheck distclean distclean-generic \
-       distclean-hdr distclean-libtool distclean-tags distcleancheck \
-       distdir distuninstallcheck dvi dvi-am html html-am info \
-       info-am install install-am install-data install-data-am \
-       install-dist_docDATA install-dvi install-dvi-am install-exec \
-       install-exec-am install-html install-html-am install-info \
-       install-info-am install-man install-pdf install-pdf-am \
-       install-ps install-ps-am install-strip installcheck \
-       installcheck-am installdirs installdirs-am maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-generic \
-       mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
-       uninstall-am uninstall-dist_docDATA
+       dist-xz dist-zip dist-zstd distcheck distclean \
+       distclean-generic distclean-hdr distclean-libtool \
+       distclean-tags distcleancheck distdir distuninstallcheck dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-dist_docDATA install-dvi \
+       install-dvi-am install-exec install-exec-am install-html \
+       install-html-am install-info install-info-am install-man \
+       install-pdf install-pdf-am install-ps install-ps-am \
+       install-strip installcheck installcheck-am installdirs \
+       installdirs-am maintainer-clean maintainer-clean-generic \
+       mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+       ps ps-am tags tags-am uninstall uninstall-am \
+       uninstall-dist_docDATA
 
 .PRECIOUS: Makefile
 
@@ -994,7 +1022,7 @@ clang-format:
        test -z $${CLANGFORMAT} && CLANGFORMAT="clang-format"; \
        $${CLANGFORMAT} -i lib/*.{c,h} lib/includes/nghttp2/*.h \
        src/*.{c,cc,h} src/includes/nghttp2/*.h examples/*.{c,cc} \
-       tests/*.{c,h}
+       tests/*.{c,h} bpf/*.c
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
index 87f6ce4..1372e3e 100644 (file)
@@ -32,12 +32,14 @@ Public Test Server
 The following endpoints are available to try out our nghttp2
 implementation.
 
-* https://nghttp2.org/ (TLS + ALPN/NPN)
+* https://nghttp2.org/ (TLS + ALPN/NPN and HTTP/3)
 
   This endpoint supports ``h2``, ``h2-16``, ``h2-14``, and
   ``http/1.1`` via ALPN/NPN and requires TLSv1.2 for HTTP/2
   connection.
 
+  It also supports HTTP/3.
+
 * http://nghttp2.org/ (HTTP Upgrade and HTTP/2 Direct)
 
   ``h2c`` and ``http/1.1``.
@@ -112,7 +114,7 @@ libnghttp2_asio C++ library requires the following packages:
 The Python bindings require the following packages:
 
 * cython >= 0.19
-* python >= 2.7
+* python >= 3.8
 * python-setuptools
 
 If you are using Ubuntu 16.04 LTS (Xenial Xerus) or Debian 8 (jessie)
@@ -145,6 +147,33 @@ minimizes the risk of private key leakage when serious bug like
 Heartbleed is exploited.  The neverbleed is disabled by default.  To
 enable it, use ``--with-neverbleed`` configure option.
 
+To enable the experimental HTTP/3 support for h2load and nghttpx, the
+following libraries are required:
+
+* `OpenSSL with QUIC support
+  <https://github.com/quictls/openssl/tree/OpenSSL_1_1_1k+quic>`_; or
+  `BoringSSL <https://boringssl.googlesource.com/boringssl/>`_ (commit
+  f6ef1c560ae5af51e2df5d8d2175bed207b28b8f)
+* `ngtcp2 <https://github.com/ngtcp2/ngtcp2>`_
+* `nghttp3 <https://github.com/ngtcp2/nghttp3>`_
+
+Use ``--enable-http3`` configure option to enable HTTP/3 feature for
+h2load and nghttpx.
+
+In order to build optional eBPF program to direct an incoming QUIC UDP
+datagram to a correct socket for nghttpx, the following libraries are
+required:
+
+* libbpf-dev >= 0.4.0
+
+Use ``--with-libbpf`` configure option to build eBPF program.
+libelf-dev is needed to build libbpf.
+
+For Ubuntu 20.04, you can build libbpf from `the source code
+<https://github.com/libbpf/libbpf/releases/tag/v0.4.0>`_.  nghttpx
+requires eBPF program for reloading its configuration and hot swapping
+its executable.
+
 Compiling libnghttp2 C source code requires a C99 compiler.  gcc 4.8
 is known to be adequate.  In order to compile the C++ source code, gcc
 >= 6.0 or clang >= 6.0 is required.  C++ source code requires C++14
@@ -307,6 +336,88 @@ The generated documents will not be installed with ``make install``.
 The online documentation is available at
 https://nghttp2.org/documentation/
 
+Build HTTP/3 enabled h2load and nghttpx
+---------------------------------------
+
+To build h2load and nghttpx with HTTP/3 feature enabled, run the
+configure script with ``--enable-http3``.
+
+For nghttpx to reload configurations and swapping its executable while
+gracefully terminating old worker processes, eBPF is required.  Run
+the configure script with ``--enable-http3 --with-libbpf`` to build
+eBPF program.  The QUIC keying material must be set with
+``--frontend-quic-secret-file`` in order to keep the existing
+connections alive during reload.
+
+The detailed steps to build HTTP/3 enabled h2load and nghttpx follow.
+
+Build custom OpenSSL:
+
+.. code-block:: text
+
+   $ git clone --depth 1 -b OpenSSL_1_1_1l+quic https://github.com/quictls/openssl
+   $ cd openssl
+   $ ./config --prefix=$PWD/build --openssldir=/etc/ssl
+   $ make -j$(nproc)
+   $ make install_sw
+   $ cd ..
+
+Build nghttp3:
+
+.. code-block:: text
+
+   $ git clone --depth 1 https://github.com/ngtcp2/nghttp3
+   $ cd nghttp3
+   $ autoreconf -i
+   $ ./configure --prefix=$PWD/build --enable-lib-only
+   $ make -j$(nproc)
+   $ make install
+   $ cd ..
+
+Build ngtcp2:
+
+.. code-block:: text
+
+   $ git clone --depth 1 https://github.com/ngtcp2/ngtcp2
+   $ cd ngtcp2
+   $ autoreconf -i
+   $ ./configure --prefix=$PWD/build --enable-lib-only \
+         PKG_CONFIG_PATH="$PWD/../openssl/build/lib/pkgconfig"
+   $ make -j$(nproc)
+   $ make install
+   $ cd ..
+
+If your Linux distribution does not have libbpf-dev >= 0.4.0, build
+from source:
+
+.. code-block:: text
+
+   $ git clone --depth 1 -b v0.4.0 https://github.com/libbpf/libbpf
+   $ cd libbpf
+   $ PREFIX=$PWD/build make -C src install
+   $ cd ..
+
+Build nghttp2:
+
+.. code-block:: text
+
+   $ git clone https://github.com/nghttp2/nghttp2
+   $ cd nghttp2
+   $ git submodule update --init
+   $ autoreconf -i
+   $ ./configure --with-mruby --with-neverbleed --enable-http3 --with-libbpf \
+         --disable-python-bindings \
+         CC=clang-12 CXX=clang++-12 \
+         PKG_CONFIG_PATH="$PWD/../openssl/build/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig:$PWD/../ngtcp2/build/lib/pkgconfig:$PWD/../libbpf/build/lib64/pkgconfig" \
+         LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/../openssl/build/lib -Wl,-rpath,$PWD/../libbpf/build/lib64"
+   $ make -j$(nproc)
+
+The eBPF program ``reuseport_kern.o`` should be found under bpf
+directory.  Pass ``--quic-bpf-program-file=bpf/reuseport_kern.o``
+option to nghttpx to load it.  See also `HTTP/3 section in nghttpx -
+HTTP/2 proxy - HOW-TO
+<https://nghttp2.org/documentation/nghttpx-howto.html#http-3>`_.
+
 Unit tests
 ----------
 
@@ -734,7 +845,7 @@ information.  Here is sample output from ``nghttpd``:
 nghttpx - proxy
 +++++++++++++++
 
-``nghttpx`` is a multi-threaded reverse proxy for HTTP/2, and
+``nghttpx`` is a multi-threaded reverse proxy for HTTP/3, HTTP/2, and
 HTTP/1.1, and powers http://nghttp2.org and supports HTTP/2 server
 push.
 
@@ -755,16 +866,16 @@ ticket keys among multiple ``nghttpx`` instances via memcached.
 
 ``nghttpx`` has 2 operation modes:
 
-================== ================ ================ =============
-Mode option        Frontend         Backend          Note
-================== ================ ================ =============
-default mode       HTTP/2, HTTP/1.1 HTTP/1.1, HTTP/2 Reverse proxy
-``--http2-proxy``  HTTP/2, HTTP/1.1 HTTP/1.1, HTTP/2 Forward proxy
-================== ================ ================ =============
+================== ======================== ================ =============
+Mode option        Frontend                 Backend          Note
+================== ======================== ================ =============
+default mode       HTTP/3, HTTP/2, HTTP/1.1 HTTP/1.1, HTTP/2 Reverse proxy
+``--http2-proxy``  HTTP/3, HTTP/2, HTTP/1.1 HTTP/1.1, HTTP/2 Forward proxy
+================== ======================== ================ =============
 
 The interesting mode at the moment is the default mode.  It works like
-a reverse proxy and listens for HTTP/2, and HTTP/1.1 and can be
-deployed as a SSL/TLS terminator for existing web server.
+a reverse proxy and listens for HTTP/3, HTTP/2, and HTTP/1.1 and can
+be deployed as a SSL/TLS terminator for existing web server.
 
 In all modes, the frontend connections are encrypted by SSL/TLS by
 default.  To disable encryption, use the ``no-tls`` keyword in
@@ -782,16 +893,16 @@ server:
 
 .. code-block:: text
 
-    Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> Web Server
-                                    [reverse proxy]
+    Client <-- (HTTP/3, HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> Web Server
+                                            [reverse proxy]
 
 With the ``--http2-proxy`` option, it works as forward proxy, and it
 is so called secure HTTP/2 proxy:
 
 .. code-block:: text
 
-    Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Proxy
-                                     [secure proxy]          (e.g., Squid, ATS)
+    Client <-- (HTTP/3, HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Proxy
+                                             [secure proxy]          (e.g., Squid, ATS)
 
 The ``Client`` in the above example needs to be configured to use
 ``nghttpx`` as secure proxy.
@@ -823,7 +934,7 @@ proxy through an HTTP proxy:
 
 .. code-block:: text
 
-    Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
+    Client <-- (HTTP/3, HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
 
             --===================---> HTTP/2 Proxy
               (HTTP proxy tunnel)     (e.g., nghttpx -s)
@@ -831,8 +942,8 @@ proxy through an HTTP proxy:
 Benchmarking tool
 -----------------
 
-The ``h2load`` program is a benchmarking tool for HTTP/2.  The UI of
-``h2load`` is heavily inspired by ``weighttp``
+The ``h2load`` program is a benchmarking tool for HTTP/3, HTTP/2, and
+HTTP/1.1.  The UI of ``h2load`` is heavily inspired by ``weighttp``
 (https://github.com/lighttpd/weighttp).  The typical usage is as
 follows:
 
@@ -875,6 +986,14 @@ threads to avoid saturating a single core on client side.
    considered a DOS attack.  Please only use it against your private
    servers.
 
+If the experimental HTTP/3 is enabled, h2load can send requests to
+HTTP/3 server.  To do this, specify ``h3`` to ``--npn-list`` option
+like so:
+
+.. code-block:: text
+
+    $ h2load --npn-list h3 https://127.0.0.1:4433
+
 HPACK tools
 -----------
 
@@ -1422,7 +1541,7 @@ The extension module is called ``nghttp2``.
 determined by the ``configure`` script.  If the detected Python version is not
 what you expect, specify a path to Python executable in a ``PYTHON``
 variable as an argument to configure script (e.g., ``./configure
-PYTHON=/usr/bin/python3.5``).
+PYTHON=/usr/bin/python3.8``).
 
 The following example code illustrates basic usage of the HPACK compressor
 and decompressor in Python:
@@ -1494,7 +1613,7 @@ BaseRequestHandler usage:
 
 .. code-block:: python
 
-    #!/usr/bin/env python
+    #!/usr/bin/env python3
 
     import io, ssl
     import nghttp2
index 698d21c..5ffa4a1 100644 (file)
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.4 -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
-[m4_warning([this file was generated for autoconf 2.69.
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],,
+[m4_warning([this file was generated for autoconf 2.71.
 You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-dnl pkg.m4 - Macros to locate and utilise pkg-config.   -*- Autoconf -*-
-dnl serial 11 (pkg-config-0.29)
-dnl
+# pkg.m4 - Macros to locate and utilise pkg-config.   -*- Autoconf -*-
+# serial 12 (pkg-config-0.29.2)
+
 dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
 dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
 dnl
@@ -63,7 +63,7 @@ dnl
 dnl See the "Since" comment for each macro you use to see what version
 dnl of the macros you require.
 m4_defun([PKG_PREREQ],
-[m4_define([PKG_MACROS_VERSION], [0.29])
+[m4_define([PKG_MACROS_VERSION], [0.29.2])
 m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
     [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
 ])dnl PKG_PREREQ
@@ -164,7 +164,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
 AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
 
 pkg_failed=no
-AC_MSG_CHECKING([for $1])
+AC_MSG_CHECKING([for $2])
 
 _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
 _PKG_CONFIG([$1][_LIBS], [libs], [$2])
@@ -174,11 +174,11 @@ and $1[]_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.])
 
 if test $pkg_failed = yes; then
-       AC_MSG_RESULT([no])
+        AC_MSG_RESULT([no])
         _PKG_SHORT_ERRORS_SUPPORTED
         if test $_pkg_short_errors_supported = yes; then
                $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
-        else 
+        else
                $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
@@ -195,7 +195,7 @@ installed software in a non-standard prefix.
 _PKG_TEXT])[]dnl
         ])
 elif test $pkg_failed = untried; then
-       AC_MSG_RESULT([no])
+        AC_MSG_RESULT([no])
        m4_default([$4], [AC_MSG_FAILURE(
 [The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
@@ -296,7 +296,7 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
 AS_VAR_IF([$1], [""], [$5], [$4])dnl
 ])dnl PKG_CHECK_VAR
 
-# Copyright (C) 2002-2018 Free Software Foundation, Inc.
+# Copyright (C) 2002-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -311,7 +311,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
 [am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.16.1], [],
+m4_if([$1], [1.16.4], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -327,14 +327,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.16.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.4])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -386,7 +386,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -417,7 +417,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -608,7 +608,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -647,7 +647,9 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   done
   if test $am_rc -ne 0; then
     AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE="gmake" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).])
   fi
@@ -674,7 +676,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -738,7 +740,7 @@ m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
 [_AM_SET_OPTIONS([$1])dnl
 dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
 m4_if(
-  m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]),
   [ok:ok],,
   [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
  AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
@@ -790,6 +792,20 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
                  [m4_define([AC_PROG_OBJCXX],
                             m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
 ])
+# Variables for tags utilities; see am/tags.am
+if test -z "$CTAGS"; then
+  CTAGS=ctags
+fi
+AC_SUBST([CTAGS])
+if test -z "$ETAGS"; then
+  ETAGS=etags
+fi
+AC_SUBST([ETAGS])
+if test -z "$CSCOPE"; then
+  CSCOPE=cscope
+fi
+AC_SUBST([CSCOPE])
+
 AC_REQUIRE([AM_SILENT_RULES])dnl
 dnl The testsuite driver may need to know about EXEEXT, so add the
 dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
@@ -871,7 +887,7 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -892,7 +908,7 @@ if test x"${install_sh+set}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2018 Free Software Foundation, Inc.
+# Copyright (C) 2003-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -913,7 +929,7 @@ AC_SUBST([am__leading_dot])])
 
 # Check to see how 'make' treats includes.                 -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -956,7 +972,7 @@ AC_SUBST([am__quote])])
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -977,12 +993,7 @@ AC_DEFUN([AM_MISSING_HAS_RUN],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 AC_REQUIRE_AUX_FILE([missing])dnl
 if test x"${MISSING+set}" != xset; then
-  case $am_aux_dir in
-  *\ * | *\    *)
-    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
-  *)
-    MISSING="\${SHELL} $am_aux_dir/missing" ;;
-  esac
+  MISSING="\${SHELL} '$am_aux_dir/missing'"
 fi
 # Use eval to expand $SHELL
 if eval "$MISSING --is-lightweight"; then
@@ -995,7 +1006,7 @@ fi
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1024,7 +1035,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1071,7 +1082,7 @@ AC_LANG_POP([C])])
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1154,21 +1165,90 @@ AC_DEFUN([AM_PATH_PYTHON],
     m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
   else
 
-  dnl Query Python for its version number.  Getting [:3] seems to be
-  dnl the best way to do this; it's what "site.py" does in the standard
-  dnl library.
+  dnl Query Python for its version number.  Although site.py simply uses
+  dnl sys.version[:3], printing that failed with Python 3.10, since the
+  dnl trailing zero was eliminated. So now we output just the major
+  dnl and minor version numbers, as numbers. Apparently the tertiary
+  dnl version is not of interest.
 
   AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
-    [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
+    [am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[[:2]])"`])
   AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
 
-  dnl Use the values of $prefix and $exec_prefix for the corresponding
+  dnl Use the values of sys.prefix and sys.exec_prefix for the corresponding
   dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX.  These are made
   dnl distinct variables so they can be overridden if need be.  However,
   dnl general consensus is that you shouldn't need this ability.
+  dnl Also allow directly setting the prefixes via configure args.
+
+  if test "x$prefix" = xNONE
+  then
+   am__usable_prefix=$ac_default_prefix
+  else
+   am__usable_prefix=$prefix
+  fi
 
-  AC_SUBST([PYTHON_PREFIX], ['${prefix}'])
-  AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}'])
+  AC_ARG_WITH([python_prefix],
+  [AS_HELP_STRING([--with-python_prefix],
+                 [override the default PYTHON_PREFIX])],
+  [ am_python_prefix_subst="$withval"
+   am_cv_python_prefix="$withval"
+   AC_MSG_CHECKING([for $am_display_PYTHON prefix])
+   AC_MSG_RESULT([$am_cv_python_prefix])],
+  [
+  AC_CACHE_CHECK([for $am_display_PYTHON prefix], [am_cv_python_prefix],
+    [am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"`])
+
+  dnl If sys.prefix is a subdir of $prefix, replace the literal value of $prefix
+  dnl with a variable reference so it can be overridden.
+  case $am_cv_python_prefix in
+     $am__usable_prefix*)
+       am__strip_prefix=`echo "$am__usable_prefix" | sed 's|.|.|g'`
+       am_python_prefix_subst=`echo "$am_cv_python_prefix" | sed "s,^$am__strip_prefix,\\${prefix},"`
+       ;;
+     *)
+       am_python_prefix_subst=$am_cv_python_prefix
+       ;;
+  esac
+  ])
+  AC_SUBST([PYTHON_PREFIX], [$am_python_prefix_subst])
+
+  AC_ARG_WITH([python_exec_prefix],
+  [AS_HELP_STRING([--with-python_exec_prefix],
+                 [override the default PYTHON_EXEC_PREFIX])],
+  [ am_python_exec_prefix_subst="$withval"
+   am_cv_python_exec_prefix="$withval"
+   AC_MSG_CHECKING([for $am_display_PYTHON exec_prefix])
+   AC_MSG_RESULT([$am_cv_python_exec_prefix])],
+  [
+  dnl --with-python_prefix was given - use its value for python_exec_prefix too
+  AS_IF([test -n "$with_python_prefix"], [am_python_exec_prefix_subst="$with_python_prefix"
+  am_cv_python_exec_prefix="$with_python_prefix"
+  AC_MSG_CHECKING([for $am_display_PYTHON exec_prefix])
+  AC_MSG_RESULT([$am_cv_python_exec_prefix])],
+  [
+  AC_CACHE_CHECK([for $am_display_PYTHON exec_prefix], [am_cv_python_exec_prefix],
+    [am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"`])
+  dnl If sys.exec_prefix is a subdir of $exec_prefix, replace the
+  dnl literal value of $exec_prefix with a variable reference so it can
+  dnl be overridden.
+  if test "x$exec_prefix" = xNONE
+  then
+   am__usable_exec_prefix=$am__usable_prefix
+  else
+   am__usable_exec_prefix=$exec_prefix
+  fi
+  case $am_cv_python_exec_prefix in
+     $am__usable_exec_prefix*)
+       am__strip_prefix=`echo "$am__usable_exec_prefix" | sed 's|.|.|g'`
+       am_python_exec_prefix_subst=`echo "$am_cv_python_exec_prefix" | sed "s,^$am__strip_prefix,\\${exec_prefix},"`
+       ;;
+     *)
+       am_python_exec_prefix_subst=$am_cv_python_exec_prefix
+       ;;
+  esac
+  ])])
+  AC_SUBST([PYTHON_EXEC_PREFIX], [$am_python_exec_prefix_subst])
 
   dnl At times (like when building shared libraries) you may want
   dnl to know which OS platform Python thinks this is.
@@ -1206,11 +1286,11 @@ except ImportError:
   dnl Query distutils for this directory.
   AC_CACHE_CHECK([for $am_display_PYTHON script directory],
     [am_cv_python_pythondir],
-    [if test "x$prefix" = xNONE
+    [if test "x$am_cv_python_prefix" = x
      then
-       am_py_prefix=$ac_default_prefix
+       am_py_prefix=$am__usable_prefix
      else
-       am_py_prefix=$prefix
+       am_py_prefix=$am_cv_python_prefix
      fi
      am_cv_python_pythondir=`$PYTHON -c "
 $am_python_setup_sysconfig
@@ -1223,13 +1303,13 @@ sys.stdout.write(sitedir)"`
      case $am_cv_python_pythondir in
      $am_py_prefix*)
        am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
-       am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
+       am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,\\${PYTHON_PREFIX},"`
        ;;
      *)
        case $am_py_prefix in
          /usr|/System*) ;;
          *)
-         am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
+         am_cv_python_pythondir="\${PYTHON_PREFIX}/lib/python$PYTHON_VERSION/site-packages"
          ;;
        esac
        ;;
@@ -1248,30 +1328,30 @@ sys.stdout.write(sitedir)"`
   dnl Query distutils for this directory.
   AC_CACHE_CHECK([for $am_display_PYTHON extension module directory],
     [am_cv_python_pyexecdir],
-    [if test "x$exec_prefix" = xNONE
+    [if test "x$am_cv_python_exec_prefix" = x
      then
-       am_py_exec_prefix=$am_py_prefix
+       am_py_exec_prefix=$am__usable_exec_prefix
      else
-       am_py_exec_prefix=$exec_prefix
+       am_py_exec_prefix=$am_cv_python_exec_prefix
      fi
      am_cv_python_pyexecdir=`$PYTHON -c "
 $am_python_setup_sysconfig
 if can_use_sysconfig:
-    sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
+    sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'})
 else:
     from distutils import sysconfig
-    sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
+    sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix')
 sys.stdout.write(sitedir)"`
      case $am_cv_python_pyexecdir in
      $am_py_exec_prefix*)
        am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
-       am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
+       am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,\\${PYTHON_EXEC_PREFIX},"`
        ;;
      *)
        case $am_py_exec_prefix in
          /usr|/System*) ;;
          *)
-          am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
+          am_cv_python_pyexecdir="\${PYTHON_EXEC_PREFIX}/lib/python$PYTHON_VERSION/site-packages"
           ;;
        esac
        ;;
@@ -1309,7 +1389,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
 sys.exit(sys.hexversion < minverhex)"
   AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1328,7 +1408,7 @@ AC_DEFUN([AM_RUN_LOG],
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1409,7 +1489,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2018 Free Software Foundation, Inc.
+# Copyright (C) 2009-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1469,7 +1549,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1497,7 +1577,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2018 Free Software Foundation, Inc.
+# Copyright (C) 2006-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1516,7 +1596,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2018 Free Software Foundation, Inc.
+# Copyright (C) 2004-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/bpf/CMakeLists.txt b/bpf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..904b821
--- /dev/null
@@ -0,0 +1,13 @@
+if(LIBBPF_FOUND)
+  add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/reuseport_kern.o"
+    COMMAND ${CMAKE_C_COMPILER} ${BPFCFLAGS} ${EXTRABPFCFLAGS} -I${LIBBPF_INCLUDE_DIRS} -target bpf -c reuseport_kern.c -o "${CMAKE_CURRENT_BINARY_DIR}/reuseport_kern.o"
+    WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+    VERBATIM)
+
+  add_custom_target(bpf ALL
+    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/reuseport_kern.o"
+    VERBATIM)
+
+  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/reuseport_kern.o"
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/${CMAKE_PROJECT_NAME}")
+endif()
diff --git a/bpf/Makefile.am b/bpf/Makefile.am
new file mode 100644 (file)
index 0000000..9017fd9
--- /dev/null
@@ -0,0 +1,40 @@
+# nghttp2 - HTTP/2 C Library
+
+# Copyright (c) 2021 Tatsuhiro Tsujikawa
+
+# 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.
+
+EXTRA_DIST = CMakeLists.txt reuseport_kern.c
+
+if HAVE_LIBBPF
+
+bpf_pkglibdir = $(pkglibdir)
+bpf_pkglib_DATA = reuseport_kern.o
+
+all: $(builddir)/reuseport_kern.o
+
+$(builddir)/reuseport_kern.o: reuseport_kern.c
+       $(CC) @LIBBPF_CFLAGS@ @BPFCFLAGS@ @EXTRABPFCFLAGS@ \
+         -target bpf -c $< -o $@
+
+clean-local:
+       -rm -f reuseport_kern.o
+
+endif # HAVE_LIBBPF
diff --git a/bpf/Makefile.in b/bpf/Makefile.in
new file mode 100644 (file)
index 0000000..1f5768e
--- /dev/null
@@ -0,0 +1,618 @@
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# nghttp2 - HTTP/2 C Library
+
+# Copyright (c) 2021 Tatsuhiro Tsujikawa
+
+# 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.
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \  ]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = bpf
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_asio.m4 \
+       $(top_srcdir)/m4/ax_boost_base.m4 \
+       $(top_srcdir)/m4/ax_boost_system.m4 \
+       $(top_srcdir)/m4/ax_boost_thread.m4 \
+       $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+       $(top_srcdir)/m4/ax_python_devel.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(bpf_pkglibdir)"
+DATA = $(bpf_pkglib_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APPLDFLAGS = @APPLDFLAGS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BOOST_ASIO_LIB = @BOOST_ASIO_LIB@
+BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
+BOOST_LDFLAGS = @BOOST_LDFLAGS@
+BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
+BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CUNIT_CFLAGS = @CUNIT_CFLAGS@
+CUNIT_LIBS = @CUNIT_LIBS@
+CXX = @CXX@
+CXX1XCXXFLAGS = @CXX1XCXXFLAGS@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+CYTHON = @CYTHON@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
+EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_CXX14 = @HAVE_CXX14@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+JANSSON_CFLAGS = @JANSSON_CFLAGS@
+JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
+JEMALLOC_LIBS = @JEMALLOC_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
+LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
+LIBCARES_LIBS = @LIBCARES_LIBS@
+LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
+LIBEVENT_OPENSSL_LIBS = @LIBEVENT_OPENSSL_LIBS@
+LIBEV_CFLAGS = @LIBEV_CFLAGS@
+LIBEV_LIBS = @LIBEV_LIBS@
+LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
+LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
+LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
+LIBXML2_LIBS = @LIBXML2_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_REVISION = @LT_REVISION@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_NUM = @PACKAGE_VERSION_NUM@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_LIBS = @PYTHON_LIBS@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
+TESTLDADD = @TESTLDADD@
+VERSION = @VERSION@
+WARNCFLAGS = @WARNCFLAGS@
+WARNCXXFLAGS = @WARNCXXFLAGS@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = CMakeLists.txt reuseport_kern.c
+@HAVE_LIBBPF_TRUE@bpf_pkglibdir = $(pkglibdir)
+@HAVE_LIBBPF_TRUE@bpf_pkglib_DATA = reuseport_kern.o
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+               && { if test -f $@; then exit 0; else break; fi; }; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu bpf/Makefile'; \
+       $(am__cd) $(top_srcdir) && \
+         $(AUTOMAKE) --gnu bpf/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+install-bpf_pkglibDATA: $(bpf_pkglib_DATA)
+       @$(NORMAL_INSTALL)
+       @list='$(bpf_pkglib_DATA)'; test -n "$(bpf_pkglibdir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(bpf_pkglibdir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(bpf_pkglibdir)" || exit 1; \
+       fi; \
+       for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         echo "$$d$$p"; \
+       done | $(am__base_list) | \
+       while read files; do \
+         echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(bpf_pkglibdir)'"; \
+         $(INSTALL_DATA) $$files "$(DESTDIR)$(bpf_pkglibdir)" || exit $$?; \
+       done
+
+uninstall-bpf_pkglibDATA:
+       @$(NORMAL_UNINSTALL)
+       @list='$(bpf_pkglib_DATA)'; test -n "$(bpf_pkglibdir)" || list=; \
+       files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+       dir='$(DESTDIR)$(bpf_pkglibdir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+       list='$(DISTFILES)'; \
+         dist_files=`for file in $$list; do echo $$file; done | \
+         sed -e "s|^$$srcdirstrip/||;t" \
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+       case $$dist_files in \
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+                          sort -u` ;; \
+       esac; \
+       for file in $$dist_files; do \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         if test -d $$d/$$file; then \
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+           if test -d "$(distdir)/$$file"; then \
+             find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+           fi; \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+             find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+           fi; \
+           cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+         else \
+           test -f "$(distdir)/$$file" \
+           || cp -p $$d/$$file "$(distdir)/$$file" \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+       for dir in "$(DESTDIR)$(bpf_pkglibdir)"; do \
+         test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+       done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+       -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+@HAVE_LIBBPF_FALSE@clean-local:
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-bpf_pkglibDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-bpf_pkglibDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+       clean-local cscopelist-am ctags-am distclean distclean-generic \
+       distclean-libtool distdir dvi dvi-am html html-am info info-am \
+       install install-am install-bpf_pkglibDATA install-data \
+       install-data-am install-dvi install-dvi-am install-exec \
+       install-exec-am install-html install-html-am install-info \
+       install-info-am install-man install-pdf install-pdf-am \
+       install-ps install-ps-am install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
+       mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+       uninstall-am uninstall-bpf_pkglibDATA
+
+.PRECIOUS: Makefile
+
+
+@HAVE_LIBBPF_TRUE@all: $(builddir)/reuseport_kern.o
+
+@HAVE_LIBBPF_TRUE@$(builddir)/reuseport_kern.o: reuseport_kern.c
+@HAVE_LIBBPF_TRUE@     $(CC) @LIBBPF_CFLAGS@ @BPFCFLAGS@ @EXTRABPFCFLAGS@ \
+@HAVE_LIBBPF_TRUE@       -target bpf -c $< -o $@
+
+@HAVE_LIBBPF_TRUE@clean-local:
+@HAVE_LIBBPF_TRUE@     -rm -f reuseport_kern.o
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/bpf/reuseport_kern.c b/bpf/reuseport_kern.c
new file mode 100644 (file)
index 0000000..7a48afa
--- /dev/null
@@ -0,0 +1,663 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <linux/udp.h>
+#include <linux/bpf.h>
+
+#include <bpf/bpf_helpers.h>
+
+/*
+ * How to compile:
+ *
+ * clang-12 -O2 -Wall -target bpf -g -c reuseport_kern.c -o reuseport_kern.o \
+ *   -I/path/to/kernel/include
+ *
+ * See
+ * https://www.kernel.org/doc/Documentation/kbuild/headers_install.txt
+ * how to install kernel header files.
+ */
+
+/* AES_CBC_decrypt_buffer: https://github.com/kokke/tiny-AES-c
+   License is Public Domain.  Commit hash:
+   12e7744b4919e9d55de75b7ab566326a1c8e7a67 */
+
+#define AES_BLOCKLEN                                                           \
+  16 /* Block length in bytes - AES is 128b block                              \
+        only */
+
+#define AES_KEYLEN 16 /* Key length in bytes */
+#define AES_keyExpSize 176
+
+struct AES_ctx {
+  __u8 RoundKey[AES_keyExpSize];
+};
+
+/* The number of columns comprising a state in AES. This is a constant
+   in AES. Value=4 */
+#define Nb 4
+
+#define Nk 4  /* The number of 32 bit words in a key. */
+#define Nr 10 /* The number of rounds in AES Cipher. */
+
+/* state - array holding the intermediate results during
+   decryption. */
+typedef __u8 state_t[4][4];
+
+/* The lookup-tables are marked const so they can be placed in
+   read-only storage instead of RAM The numbers below can be computed
+   dynamically trading ROM for RAM - This can be useful in (embedded)
+   bootloader applications, where ROM is often limited. */
+static const __u8 sbox[256] = {
+    /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
+    0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+    0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
+    0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
+    0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+    0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
+    0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
+    0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+    0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
+    0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
+    0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+    0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
+    0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
+    0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+    0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
+    0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
+    0xb0, 0x54, 0xbb, 0x16};
+
+static const __u8 rsbox[256] = {
+    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
+    0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
+    0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32,
+    0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
+    0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
+    0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50,
+    0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05,
+    0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
+    0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41,
+    0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
+    0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
+    0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,
+    0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59,
+    0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
+    0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d,
+    0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,
+    0x55, 0x21, 0x0c, 0x7d};
+
+/* The round constant word array, Rcon[i], contains the values given
+   by x to the power (i-1) being powers of x (x is denoted as {02}) in
+   the field GF(2^8) */
+static const __u8 Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10,
+                              0x20, 0x40, 0x80, 0x1b, 0x36};
+
+#define getSBoxValue(num) (sbox[(num)])
+
+/* This function produces Nb(Nr+1) round keys. The round keys are used
+   in each round to decrypt the states. */
+static void KeyExpansion(__u8 *RoundKey, const __u8 *Key) {
+  unsigned i, j, k;
+  __u8 tempa[4]; /* Used for the column/row operations */
+
+  /* The first round key is the key itself. */
+  for (i = 0; i < Nk; ++i) {
+    RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
+    RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
+    RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
+    RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
+  }
+
+  /* All other round keys are found from the previous round keys. */
+  for (i = Nk; i < Nb * (Nr + 1); ++i) {
+    {
+      k = (i - 1) * 4;
+      tempa[0] = RoundKey[k + 0];
+      tempa[1] = RoundKey[k + 1];
+      tempa[2] = RoundKey[k + 2];
+      tempa[3] = RoundKey[k + 3];
+    }
+
+    if (i % Nk == 0) {
+      /* This function shifts the 4 bytes in a word to the left once.
+         [a0,a1,a2,a3] becomes [a1,a2,a3,a0] */
+
+      /* Function RotWord() */
+      {
+        const __u8 u8tmp = tempa[0];
+        tempa[0] = tempa[1];
+        tempa[1] = tempa[2];
+        tempa[2] = tempa[3];
+        tempa[3] = u8tmp;
+      }
+
+      /* SubWord() is a function that takes a four-byte input word and
+         applies the S-box to each of the four bytes to produce an
+         output word. */
+
+      /* Function Subword() */
+      {
+        tempa[0] = getSBoxValue(tempa[0]);
+        tempa[1] = getSBoxValue(tempa[1]);
+        tempa[2] = getSBoxValue(tempa[2]);
+        tempa[3] = getSBoxValue(tempa[3]);
+      }
+
+      tempa[0] = tempa[0] ^ Rcon[i / Nk];
+    }
+    j = i * 4;
+    k = (i - Nk) * 4;
+    RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
+    RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
+    RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
+    RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
+  }
+}
+
+static void AES_init_ctx(struct AES_ctx *ctx, const __u8 *key) {
+  KeyExpansion(ctx->RoundKey, key);
+}
+
+/* This function adds the round key to state.  The round key is added
+   to the state by an XOR function. */
+static void AddRoundKey(__u8 round, state_t *state, const __u8 *RoundKey) {
+  __u8 i, j;
+  for (i = 0; i < 4; ++i) {
+    for (j = 0; j < 4; ++j) {
+      (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
+    }
+  }
+}
+
+static __u8 xtime(__u8 x) { return ((x << 1) ^ (((x >> 7) & 1) * 0x1b)); }
+
+#define Multiply(x, y)                                                         \
+  (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^                                 \
+   ((y >> 2 & 1) * xtime(xtime(x))) ^                                          \
+   ((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^                                   \
+   ((y >> 4 & 1) * xtime(xtime(xtime(xtime(x))))))
+
+#define getSBoxInvert(num) (rsbox[(num)])
+
+/* MixColumns function mixes the columns of the state matrix.  The
+   method used to multiply may be difficult to understand for the
+   inexperienced. Please use the references to gain more
+   information. */
+static void InvMixColumns(state_t *state) {
+  int i;
+  __u8 a, b, c, d;
+  for (i = 0; i < 4; ++i) {
+    a = (*state)[i][0];
+    b = (*state)[i][1];
+    c = (*state)[i][2];
+    d = (*state)[i][3];
+
+    (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^
+                     Multiply(d, 0x09);
+    (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^
+                     Multiply(d, 0x0d);
+    (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^
+                     Multiply(d, 0x0b);
+    (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^
+                     Multiply(d, 0x0e);
+  }
+}
+
+extern __u32 LINUX_KERNEL_VERSION __kconfig;
+
+/* The SubBytes Function Substitutes the values in the state matrix
+   with values in an S-box. */
+static void InvSubBytes(state_t *state) {
+  __u8 i, j;
+  if (LINUX_KERNEL_VERSION < KERNEL_VERSION(5, 10, 0)) {
+    for (i = 0; i < 4; ++i) {
+      for (j = 0; j < 4; ++j) {
+        /* Ubuntu 20.04 LTS kernel 5.4.0 needs this workaround
+           otherwise "math between map_value pointer and register with
+           unbounded min value is not allowed".  5.10.0 is a kernel
+           version that works but it might not be the minimum
+           version.  */
+        __u8 k = (*state)[j][i];
+        (*state)[j][i] = k ? getSBoxInvert(k) : getSBoxInvert(0);
+      }
+    }
+  } else {
+    for (i = 0; i < 4; ++i) {
+      for (j = 0; j < 4; ++j) {
+        (*state)[j][i] = getSBoxInvert((*state)[j][i]);
+      }
+    }
+  }
+}
+
+static void InvShiftRows(state_t *state) {
+  __u8 temp;
+
+  /* Rotate first row 1 columns to right */
+  temp = (*state)[3][1];
+  (*state)[3][1] = (*state)[2][1];
+  (*state)[2][1] = (*state)[1][1];
+  (*state)[1][1] = (*state)[0][1];
+  (*state)[0][1] = temp;
+
+  /* Rotate second row 2 columns to right */
+  temp = (*state)[0][2];
+  (*state)[0][2] = (*state)[2][2];
+  (*state)[2][2] = temp;
+
+  temp = (*state)[1][2];
+  (*state)[1][2] = (*state)[3][2];
+  (*state)[3][2] = temp;
+
+  /* Rotate third row 3 columns to right */
+  temp = (*state)[0][3];
+  (*state)[0][3] = (*state)[1][3];
+  (*state)[1][3] = (*state)[2][3];
+  (*state)[2][3] = (*state)[3][3];
+  (*state)[3][3] = temp;
+}
+
+static void InvCipher(state_t *state, const __u8 *RoundKey) {
+  /* Add the First round key to the state before starting the
+     rounds. */
+  AddRoundKey(Nr, state, RoundKey);
+
+  /* There will be Nr rounds.  The first Nr-1 rounds are identical.
+     These Nr rounds are executed in the loop below.  Last one without
+     InvMixColumn() */
+  InvShiftRows(state);
+  InvSubBytes(state);
+  AddRoundKey(Nr - 1, state, RoundKey);
+  InvMixColumns(state);
+
+  InvShiftRows(state);
+  InvSubBytes(state);
+  AddRoundKey(Nr - 2, state, RoundKey);
+  InvMixColumns(state);
+
+  InvShiftRows(state);
+  InvSubBytes(state);
+  AddRoundKey(Nr - 3, state, RoundKey);
+  InvMixColumns(state);
+
+  InvShiftRows(state);
+  InvSubBytes(state);
+  AddRoundKey(Nr - 4, state, RoundKey);
+  InvMixColumns(state);
+
+  InvShiftRows(state);
+  InvSubBytes(state);
+  AddRoundKey(Nr - 5, state, RoundKey);
+  InvMixColumns(state);
+
+  InvShiftRows(state);
+  InvSubBytes(state);
+  AddRoundKey(Nr - 6, state, RoundKey);
+  InvMixColumns(state);
+
+  InvShiftRows(state);
+  InvSubBytes(state);
+  AddRoundKey(Nr - 7, state, RoundKey);
+  InvMixColumns(state);
+
+  InvShiftRows(state);
+  InvSubBytes(state);
+  AddRoundKey(Nr - 8, state, RoundKey);
+  InvMixColumns(state);
+
+  InvShiftRows(state);
+  InvSubBytes(state);
+  AddRoundKey(Nr - 9, state, RoundKey);
+  InvMixColumns(state);
+
+  InvShiftRows(state);
+  InvSubBytes(state);
+  AddRoundKey(Nr - 10, state, RoundKey);
+}
+
+static void AES_ECB_decrypt(const struct AES_ctx *ctx, __u8 *buf) {
+  /* The next function call decrypts the PlainText with the Key using
+     AES algorithm. */
+  InvCipher((state_t *)buf, ctx->RoundKey);
+}
+
+/* rol32: From linux kernel source code */
+
+/**
+ * rol32 - rotate a 32-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u32 rol32(__u32 word, unsigned int shift) {
+  return (word << shift) | (word >> ((-shift) & 31));
+}
+
+/* jhash.h: Jenkins hash support.
+ *
+ * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net)
+ *
+ * https://burtleburtle.net/bob/hash/
+ *
+ * These are the credits from Bob's sources:
+ *
+ * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+ *
+ * These are functions for producing 32-bit hashes for hash table lookup.
+ * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
+ * are externally useful functions.  Routines to test the hash are included
+ * if SELF_TEST is defined.  You can use this free for any purpose.  It's in
+ * the public domain.  It has no warranty.
+ *
+ * Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
+ *
+ * I've modified Bob's hash to be useful in the Linux kernel, and
+ * any bugs present are my fault.
+ * Jozsef
+ */
+
+/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
+#define __jhash_final(a, b, c)                                                 \
+  {                                                                            \
+    c ^= b;                                                                    \
+    c -= rol32(b, 14);                                                         \
+    a ^= c;                                                                    \
+    a -= rol32(c, 11);                                                         \
+    b ^= a;                                                                    \
+    b -= rol32(a, 25);                                                         \
+    c ^= b;                                                                    \
+    c -= rol32(b, 16);                                                         \
+    a ^= c;                                                                    \
+    a -= rol32(c, 4);                                                          \
+    b ^= a;                                                                    \
+    b -= rol32(a, 14);                                                         \
+    c ^= b;                                                                    \
+    c -= rol32(b, 24);                                                         \
+  }
+
+/* __jhash_nwords - hash exactly 3, 2 or 1 word(s) */
+static inline __u32 __jhash_nwords(__u32 a, __u32 b, __u32 c, __u32 initval) {
+  a += initval;
+  b += initval;
+  c += initval;
+
+  __jhash_final(a, b, c);
+
+  return c;
+}
+
+/* An arbitrary initial parameter */
+#define JHASH_INITVAL 0xdeadbeef
+
+static inline __u32 jhash_2words(__u32 a, __u32 b, __u32 initval) {
+  return __jhash_nwords(a, b, 0, initval + JHASH_INITVAL + (2 << 2));
+}
+
+struct bpf_map_def SEC("maps") cid_prefix_map = {
+    .type = BPF_MAP_TYPE_HASH,
+    .max_entries = 255,
+    .key_size = sizeof(__u64),
+    .value_size = sizeof(__u32),
+};
+
+struct bpf_map_def SEC("maps") reuseport_array = {
+    .type = BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
+    .max_entries = 255,
+    .key_size = sizeof(__u32),
+    .value_size = sizeof(__u32),
+};
+
+struct bpf_map_def SEC("maps") sk_info = {
+    .type = BPF_MAP_TYPE_ARRAY,
+    .max_entries = 3,
+    .key_size = sizeof(__u32),
+    .value_size = sizeof(__u64),
+};
+
+typedef struct quic_hd {
+  __u8 *dcid;
+  __u32 dcidlen;
+  __u32 dcid_offset;
+  __u8 type;
+} quic_hd;
+
+#define SV_DCIDLEN 20
+#define MAX_DCIDLEN 20
+#define MIN_DCIDLEN 8
+#define CID_PREFIXLEN 8
+#define CID_PREFIX_OFFSET 1
+
+enum {
+  NGTCP2_PKT_INITIAL = 0x0,
+  NGTCP2_PKT_0RTT = 0x1,
+  NGTCP2_PKT_HANDSHAKE = 0x2,
+  NGTCP2_PKT_SHORT = 0x40,
+};
+
+static inline int parse_quic(quic_hd *qhd, __u8 *data, __u8 *data_end) {
+  __u8 *p;
+  __u64 dcidlen;
+
+  if (*data & 0x80) {
+    p = data + 1 + 4;
+
+    /* Do not check the actual DCID length because we might not buffer
+       entire DCID here. */
+    dcidlen = *p;
+
+    if (dcidlen > MAX_DCIDLEN || dcidlen < MIN_DCIDLEN) {
+      return -1;
+    }
+
+    ++p;
+
+    qhd->type = (*data & 0x30) >> 4;
+    qhd->dcid = p;
+    qhd->dcidlen = dcidlen;
+    qhd->dcid_offset = 6;
+  } else {
+    qhd->type = NGTCP2_PKT_SHORT;
+    qhd->dcid = data + 1;
+    qhd->dcidlen = SV_DCIDLEN;
+    qhd->dcid_offset = 1;
+  }
+
+  return 0;
+}
+
+static __u32 hash(const __u8 *data, __u32 datalen, __u32 initval) {
+  __u32 a, b;
+
+  a = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
+  b = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
+
+  return jhash_2words(a, b, initval);
+}
+
+static __u32 sk_index_from_dcid(const quic_hd *qhd,
+                                const struct sk_reuseport_md *reuse_md,
+                                __u64 num_socks) {
+  __u32 len = qhd->dcidlen;
+  __u32 h = reuse_md->hash;
+  __u8 hbuf[8];
+
+  if (len > 16) {
+    __builtin_memset(hbuf, 0, sizeof(hbuf));
+
+    switch (len) {
+    case 20:
+      __builtin_memcpy(hbuf, qhd->dcid + 16, 4);
+      break;
+    case 19:
+      __builtin_memcpy(hbuf, qhd->dcid + 16, 3);
+      break;
+    case 18:
+      __builtin_memcpy(hbuf, qhd->dcid + 16, 2);
+      break;
+    case 17:
+      __builtin_memcpy(hbuf, qhd->dcid + 16, 1);
+      break;
+    }
+
+    h = hash(hbuf, sizeof(hbuf), h);
+    len = 16;
+  }
+
+  if (len > 8) {
+    __builtin_memset(hbuf, 0, sizeof(hbuf));
+
+    switch (len) {
+    case 16:
+      __builtin_memcpy(hbuf, qhd->dcid + 8, 8);
+      break;
+    case 15:
+      __builtin_memcpy(hbuf, qhd->dcid + 8, 7);
+      break;
+    case 14:
+      __builtin_memcpy(hbuf, qhd->dcid + 8, 6);
+      break;
+    case 13:
+      __builtin_memcpy(hbuf, qhd->dcid + 8, 5);
+      break;
+    case 12:
+      __builtin_memcpy(hbuf, qhd->dcid + 8, 4);
+      break;
+    case 11:
+      __builtin_memcpy(hbuf, qhd->dcid + 8, 3);
+      break;
+    case 10:
+      __builtin_memcpy(hbuf, qhd->dcid + 8, 2);
+      break;
+    case 9:
+      __builtin_memcpy(hbuf, qhd->dcid + 8, 1);
+      break;
+    }
+
+    h = hash(hbuf, sizeof(hbuf), h);
+    len = 8;
+  }
+
+  return hash(qhd->dcid, len, h) % num_socks;
+}
+
+SEC("sk_reuseport")
+int select_reuseport(struct sk_reuseport_md *reuse_md) {
+  __u32 sk_index, *psk_index;
+  __u64 *pnum_socks, *pkey;
+  __u32 zero = 0, key_high_idx = 1, key_low_idx = 2;
+  int rv;
+  quic_hd qhd;
+  __u8 qpktbuf[6 + MAX_DCIDLEN];
+  struct AES_ctx aes_ctx;
+  __u8 key[AES_KEYLEN];
+  __u8 *cid_prefix;
+
+  if (bpf_skb_load_bytes(reuse_md, sizeof(struct udphdr), qpktbuf,
+                         sizeof(qpktbuf)) != 0) {
+    return SK_DROP;
+  }
+
+  pnum_socks = bpf_map_lookup_elem(&sk_info, &zero);
+  if (pnum_socks == NULL) {
+    return SK_DROP;
+  }
+
+  pkey = bpf_map_lookup_elem(&sk_info, &key_high_idx);
+  if (pkey == NULL) {
+    return SK_DROP;
+  }
+
+  __builtin_memcpy(key, pkey, sizeof(*pkey));
+
+  pkey = bpf_map_lookup_elem(&sk_info, &key_low_idx);
+  if (pkey == NULL) {
+    return SK_DROP;
+  }
+
+  __builtin_memcpy(key + sizeof(*pkey), pkey, sizeof(*pkey));
+
+  rv = parse_quic(&qhd, qpktbuf, qpktbuf + sizeof(qpktbuf));
+  if (rv != 0) {
+    return SK_DROP;
+  }
+
+  AES_init_ctx(&aes_ctx, key);
+
+  switch (qhd.type) {
+  case NGTCP2_PKT_INITIAL:
+  case NGTCP2_PKT_0RTT:
+    if (qhd.dcidlen == SV_DCIDLEN) {
+      cid_prefix = qhd.dcid + CID_PREFIX_OFFSET;
+      AES_ECB_decrypt(&aes_ctx, cid_prefix);
+
+      psk_index = bpf_map_lookup_elem(&cid_prefix_map, cid_prefix);
+      if (psk_index != NULL) {
+        sk_index = *psk_index;
+
+        break;
+      }
+    }
+
+    sk_index = sk_index_from_dcid(&qhd, reuse_md, *pnum_socks);
+
+    break;
+  case NGTCP2_PKT_HANDSHAKE:
+  case NGTCP2_PKT_SHORT:
+    if (qhd.dcidlen != SV_DCIDLEN) {
+      return SK_DROP;
+    }
+
+    cid_prefix = qhd.dcid + CID_PREFIX_OFFSET;
+    AES_ECB_decrypt(&aes_ctx, cid_prefix);
+
+    psk_index = bpf_map_lookup_elem(&cid_prefix_map, cid_prefix);
+    if (psk_index == NULL) {
+      sk_index = sk_index_from_dcid(&qhd, reuse_md, *pnum_socks);
+
+      break;
+    }
+
+    sk_index = *psk_index;
+
+    break;
+  default:
+    return SK_DROP;
+  }
+
+  rv = bpf_sk_select_reuseport(reuse_md, &reuseport_array, &sk_index, 0);
+  if (rv != 0) {
+    return SK_DROP;
+  }
+
+  return SK_PASS;
+}
diff --git a/cmake/FindLibbpf.cmake b/cmake/FindLibbpf.cmake
new file mode 100644 (file)
index 0000000..7f76255
--- /dev/null
@@ -0,0 +1,32 @@
+# - Try to find libbpf
+# Once done this will define
+#  LIBBPF_FOUND        - System has libbpf
+#  LIBBPF_INCLUDE_DIRS - The libbpf include directories
+#  LIBBPF_LIBRARIES    - The libraries needed to use libbpf
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_LIBBPF QUIET libbpf)
+
+find_path(LIBBPF_INCLUDE_DIR
+  NAMES bpf/bpf.h
+  HINTS ${PC_LIBBPF_INCLUDE_DIRS}
+)
+find_library(LIBBPF_LIBRARY
+  NAMES bpf
+  HINTS ${PC_LIBBPF_LIBRARY_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set LIBBPF_FOUND
+# to TRUE if all listed variables are TRUE and the requested version
+# matches.
+find_package_handle_standard_args(Libbpf REQUIRED_VARS
+                                  LIBBPF_LIBRARY LIBBPF_INCLUDE_DIR
+                                  VERSION_VAR LIBBPF_VERSION)
+
+if(LIBBPF_FOUND)
+  set(LIBBPF_LIBRARIES     ${LIBBPF_LIBRARY})
+  set(LIBBPF_INCLUDE_DIRS  ${LIBBPF_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(LIBBPF_INCLUDE_DIR LIBBPF_LIBRARY)
diff --git a/cmake/FindLibnghttp3.cmake b/cmake/FindLibnghttp3.cmake
new file mode 100644 (file)
index 0000000..ecd01f6
--- /dev/null
@@ -0,0 +1,41 @@
+# - Try to find libnghttp3
+# Once done this will define
+#  LIBNGHTTP3_FOUND        - System has libnghttp3
+#  LIBNGHTTP3_INCLUDE_DIRS - The libnghttp3 include directories
+#  LIBNGHTTP3_LIBRARIES    - The libraries needed to use libnghttp3
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_LIBNGHTTP3 QUIET libnghttp3)
+
+find_path(LIBNGHTTP3_INCLUDE_DIR
+  NAMES nghttp3/nghttp3.h
+  HINTS ${PC_LIBNGHTTP3_INCLUDE_DIRS}
+)
+find_library(LIBNGHTTP3_LIBRARY
+  NAMES nghttp3
+  HINTS ${PC_LIBNGHTTP3_LIBRARY_DIRS}
+)
+
+if(LIBNGHTTP3_INCLUDE_DIR)
+  set(_version_regex "^#define[ \t]+NGHTTP3_VERSION[ \t]+\"([^\"]+)\".*")
+  file(STRINGS "${LIBNGHTTP3_INCLUDE_DIR}/nghttp3/version.h"
+    LIBNGHTTP3_VERSION REGEX "${_version_regex}")
+  string(REGEX REPLACE "${_version_regex}" "\\1"
+    LIBNGHTTP3_VERSION "${LIBNGHTTP3_VERSION}")
+  unset(_version_regex)
+endif()
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set LIBNGHTTP3_FOUND
+# to TRUE if all listed variables are TRUE and the requested version
+# matches.
+find_package_handle_standard_args(Libnghttp3 REQUIRED_VARS
+                                  LIBNGHTTP3_LIBRARY LIBNGHTTP3_INCLUDE_DIR
+                                  VERSION_VAR LIBNGHTTP3_VERSION)
+
+if(LIBNGHTTP3_FOUND)
+  set(LIBNGHTTP3_LIBRARIES     ${LIBNGHTTP3_LIBRARY})
+  set(LIBNGHTTP3_INCLUDE_DIRS  ${LIBNGHTTP3_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(LIBNGHTTP3_INCLUDE_DIR LIBNGHTTP3_LIBRARY)
diff --git a/cmake/FindLibngtcp2.cmake b/cmake/FindLibngtcp2.cmake
new file mode 100644 (file)
index 0000000..c670114
--- /dev/null
@@ -0,0 +1,41 @@
+# - Try to find libngtcp2
+# Once done this will define
+#  LIBNGTCP2_FOUND        - System has libngtcp2
+#  LIBNGTCP2_INCLUDE_DIRS - The libngtcp2 include directories
+#  LIBNGTCP2_LIBRARIES    - The libraries needed to use libngtcp2
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_LIBNGTCP2 QUIET libngtcp2)
+
+find_path(LIBNGTCP2_INCLUDE_DIR
+  NAMES ngtcp2/ngtcp2.h
+  HINTS ${PC_LIBNGTCP2_INCLUDE_DIRS}
+)
+find_library(LIBNGTCP2_LIBRARY
+  NAMES ngtcp2
+  HINTS ${PC_LIBNGTCP2_LIBRARY_DIRS}
+)
+
+if(LIBNGTCP2_INCLUDE_DIR)
+  set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
+  file(STRINGS "${LIBNGTCP2_INCLUDE_DIR}/ngtcp2/version.h"
+    LIBNGTCP2_VERSION REGEX "${_version_regex}")
+  string(REGEX REPLACE "${_version_regex}" "\\1"
+    LIBNGTCP2_VERSION "${LIBNGTCP2_VERSION}")
+  unset(_version_regex)
+endif()
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set LIBNGTCP2_FOUND
+# to TRUE if all listed variables are TRUE and the requested version
+# matches.
+find_package_handle_standard_args(Libngtcp2 REQUIRED_VARS
+                                  LIBNGTCP2_LIBRARY LIBNGTCP2_INCLUDE_DIR
+                                  VERSION_VAR LIBNGTCP2_VERSION)
+
+if(LIBNGTCP2_FOUND)
+  set(LIBNGTCP2_LIBRARIES     ${LIBNGTCP2_LIBRARY})
+  set(LIBNGTCP2_INCLUDE_DIRS  ${LIBNGTCP2_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(LIBNGTCP2_INCLUDE_DIR LIBNGTCP2_LIBRARY)
diff --git a/cmake/FindLibngtcp2_crypto_openssl.cmake b/cmake/FindLibngtcp2_crypto_openssl.cmake
new file mode 100644 (file)
index 0000000..8df7859
--- /dev/null
@@ -0,0 +1,43 @@
+# - Try to find libngtcp2_crypto_openssl
+# Once done this will define
+#  LIBNGTCP2_CRYPTO_OPENSSL_FOUND        - System has libngtcp2_crypto_openssl
+#  LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIRS - The libngtcp2_crypto_openssl include directories
+#  LIBNGTCP2_CRYPTO_OPENSSL_LIBRARIES    - The libraries needed to use libngtcp2_crypto_openssl
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_LIBNGTCP2_CRYPTO_OPENSSL QUIET libngtcp2_crypto_openssl)
+
+find_path(LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR
+  NAMES ngtcp2/ngtcp2_crypto_openssl.h
+  HINTS ${PC_LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIRS}
+)
+find_library(LIBNGTCP2_CRYPTO_OPENSSL_LIBRARY
+  NAMES ngtcp2_crypto_openssl
+  HINTS ${PC_LIBNGTCP2_CRYPTO_OPENSSL_LIBRARY_DIRS}
+)
+
+if(LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR)
+  set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
+  file(STRINGS "${LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR}/ngtcp2/version.h"
+    LIBNGTCP2_CRYPTO_OPENSSL_VERSION REGEX "${_version_regex}")
+  string(REGEX REPLACE "${_version_regex}" "\\1"
+    LIBNGTCP2_CRYPTO_OPENSSL_VERSION "${LIBNGTCP2_CRYPTO_OPENSSL_VERSION}")
+  unset(_version_regex)
+endif()
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set
+# LIBNGTCP2_CRYPTO_OPENSSL_FOUND to TRUE if all listed variables are
+# TRUE and the requested version matches.
+find_package_handle_standard_args(Libngtcp2_crypto_openssl REQUIRED_VARS
+                                  LIBNGTCP2_CRYPTO_OPENSSL_LIBRARY
+                                  LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR
+                                  VERSION_VAR LIBNGTCP2_CRYPTO_OPENSSL_VERSION)
+
+if(LIBNGTCP2_CRYPTO_OPENSSL_FOUND)
+  set(LIBNGTCP2_CRYPTO_OPENSSL_LIBRARIES ${LIBNGTCP2_CRYPTO_OPENSSL_LIBRARY})
+  set(LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIRS ${LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR
+                 LIBNGTCP2_CRYPTO_OPENSSL_LIBRARY)
diff --git a/cmake/FindSpdylay.cmake b/cmake/FindSpdylay.cmake
deleted file mode 100644 (file)
index 6a76d28..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-# - Try to find spdylay
-# Once done this will define
-#  SPDYLAY_FOUND        - System has spdylay
-#  SPDYLAY_INCLUDE_DIRS - The spdylay include directories
-#  SPDYLAY_LIBRARIES    - The libraries needed to use spdylay
-
-find_package(PkgConfig QUIET)
-pkg_check_modules(PC_SPDYLAY QUIET libspdylay)
-
-find_path(SPDYLAY_INCLUDE_DIR
-  NAMES spdylay/spdylay.h
-  HINTS ${PC_SPDYLAY_INCLUDE_DIRS}
-)
-find_library(SPDYLAY_LIBRARY
-  NAMES spdylay
-  HINTS ${PC_SPDYLAY_LIBRARY_DIRS}
-)
-
-if(SPDYLAY_INCLUDE_DIR)
-  set(_version_regex "^#define[ \t]+SPDYLAY_VERSION[ \t]+\"([^\"]+)\".*")
-  file(STRINGS "${SPDYLAY_INCLUDE_DIR}/spdylay/spdylayver.h"
-    SPDYLAY_VERSION REGEX "${_version_regex}")
-  string(REGEX REPLACE "${_version_regex}" "\\1"
-    SPDYLAY_VERSION "${SPDYLAY_VERSION}")
-  unset(_version_regex)
-endif()
-
-include(FindPackageHandleStandardArgs)
-# handle the QUIETLY and REQUIRED arguments and set SPDYLAY_FOUND to TRUE
-# if all listed variables are TRUE and the requested version matches.
-find_package_handle_standard_args(Spdylay REQUIRED_VARS
-                                  SPDYLAY_LIBRARY SPDYLAY_INCLUDE_DIR
-                                  VERSION_VAR SPDYLAY_VERSION)
-
-if(SPDYLAY_FOUND)
-  set(SPDYLAY_LIBRARIES     ${SPDYLAY_LIBRARY})
-  set(SPDYLAY_INCLUDE_DIRS  ${SPDYLAY_INCLUDE_DIR})
-endif()
-
-mark_as_advanced(SPDYLAY_INCLUDE_DIR SPDYLAY_LIBRARY)
diff --git a/cmake/FindSystemd.cmake b/cmake/FindSystemd.cmake
new file mode 100644 (file)
index 0000000..e7534e5
--- /dev/null
@@ -0,0 +1,19 @@
+# - Try to find systemd
+# Once done this will define
+#  SYSTEMD_FOUND        - System has systemd
+#  SYSTEMD_INCLUDE_DIRS - The systemd include directories
+#  SYSTEMD_LIBRARIES    - The libraries needed to use systemd
+
+include(FeatureSummary)
+set_package_properties(Systemd PROPERTIES
+        URL "http://freedesktop.org/wiki/Software/systemd/"
+        DESCRIPTION "System and Service Manager")
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_SYSTEMD QUIET libsystemd)
+find_library(SYSTEMD_LIBRARIES NAMES systemd ${PC_SYSTEMD_LIBRARY_DIRS})
+find_path(SYSTEMD_INCLUDE_DIRS systemd/sd-login.h HINTS ${PC_SYSTEMD_INCLUDE_DIRS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Systemd DEFAULT_MSG SYSTEMD_INCLUDE_DIRS SYSTEMD_LIBRARIES)
+mark_as_advanced(SYSTEMD_INCLUDE_DIRS SYSTEMD_LIBRARIES)
index d67b540..2e357d5 100644 (file)
@@ -13,9 +13,6 @@
 /* Define to 1 if you have `libxml2` library. */
 #cmakedefine HAVE_LIBXML2 1
 
-/* Define to 1 if you have `spdylay` library. */
-#cmakedefine HAVE_SPDYLAY 1
-
 /* Define to 1 if you have `mruby` library. */
 #cmakedefine HAVE_MRUBY 1
 
 
 /* Define to 1 if you have the <unistd.h> header file. */
 #cmakedefine HAVE_UNISTD_H 1
+
+/* Define to 1 if HTTP/3 is enabled. */
+#cmakedefine ENABLE_HTTP3 1
+
+/* Define to 1 if you have `libbpf` library. */
+#cmakedefine HAVE_LIBBPF 1
+
+/* Define to 1 if you have enum bpf_stats_type in linux/bpf.h. */
+#cmakedefine HAVE_BPF_STATS_TYPE 1
+
+/* Define to 1 if you have `libngtcp2_crypto_openssl` library. */
+#cmakedefine HAVE_LIBNGTCP2_CRYPTO_OPENSSL
diff --git a/compile b/compile
index 99e5052..df363c8 100755 (executable)
--- a/compile
+++ b/compile
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@ func_file_conv ()
          MINGW*)
            file_conv=mingw
            ;;
-         CYGWIN*)
+         CYGWIN* | MSYS*)
            file_conv=cygwin
            ;;
          *)
@@ -67,7 +67,7 @@ func_file_conv ()
        mingw/*)
          file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
          ;;
-       cygwin/*)
+       cygwin/* | msys/*)
          file=`cygpath -m "$file" || echo "$file"`
          ;;
        wine/*)
index eb3dbad..cd0616c 100644 (file)
@@ -6,6 +6,9 @@
 /* Define to 1 to enable debug output. */
 #undef DEBUGBUILD
 
+/* Define to 1 if HTTP/3 is enabled. */
+#undef ENABLE_HTTP3
+
 /* Define to 1 if you have the `accept4' function. */
 #undef HAVE_ACCEPT4
 
@@ -27,6 +30,9 @@
 /* define if the Boost::Thread library is available */
 #undef HAVE_BOOST_THREAD
 
+/* Define to 1 if you have enum bpf_stats_type in linux/bpf.h. */
+#undef HAVE_BPF_STATS_TYPE
+
 /* Define to 1 if your system has a working `chown' function. */
 #undef HAVE_CHOWN
 
 /* Define to 1 if you have `libjansson` library. */
 #undef HAVE_JANSSON
 
+/* Define to 1 if you have `libbpf` library. */
+#undef HAVE_LIBBPF
+
+/* Define to 1 if you have `libngtcp2_crypto_boringssl` library. */
+#undef HAVE_LIBNGTCP2_CRYPTO_BORINGSSL
+
+/* Define to 1 if you have `libngtcp2_crypto_openssl` library. */
+#undef HAVE_LIBNGTCP2_CRYPTO_OPENSSL
+
 /* Define to 1 if you have `libsystemd` library. */
 #undef HAVE_LIBSYSTEMD
 
 /* Define to 1 if you have the `memmove' function. */
 #undef HAVE_MEMMOVE
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
 /* Define to 1 if you have the `memset' function. */
 #undef HAVE_MEMSET
 
+/* Define to 1 if you have the <minix/config.h> header file. */
+#undef HAVE_MINIX_CONFIG_H
+
 /* Define to 1 if you have the `mkostemp' function. */
 #undef HAVE_MKOSTEMP
 
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
 /* Define to 1 if you have the `strerror' function. */
 #undef HAVE_STRERROR
 
-/* Define to 1 if you have the `strerror_r' function. */
+/* Define if you have `strerror_r'. */
 #undef HAVE_STRERROR_R
 
 /* Define to 1 if you have the <strings.h> header file. */
 /* Define to 1 if you have the <vfork.h> header file. */
 #undef HAVE_VFORK_H
 
+/* Define to 1 if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
 /* Define to 1 if `fork' works. */
 #undef HAVE_WORKING_FORK
 
 /* The size of `time_t', as computed by sizeof. */
 #undef SIZEOF_TIME_T
 
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #undef STDC_HEADERS
 
 /* Define to 1 if strerror_r returns char *. */
 #ifndef _ALL_SOURCE
 # undef _ALL_SOURCE
 #endif
+/* Enable general extensions on macOS.  */
+#ifndef _DARWIN_C_SOURCE
+# undef _DARWIN_C_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
 /* Enable GNU extensions on systems that have them.  */
 #ifndef _GNU_SOURCE
 # undef _GNU_SOURCE
 #endif
-/* Enable threading extensions on Solaris.  */
+/* Enable X/Open compliant socket functions that do not require linking
+   with -lxnet on HP-UX 11.11.  */
+#ifndef _HPUX_ALT_XOPEN_SOCKET_API
+# undef _HPUX_ALT_XOPEN_SOCKET_API
+#endif
+/* Identify the host operating system as Minix.
+   This macro does not affect the system headers' behavior.
+   A future release of Autoconf may stop defining this macro.  */
+#ifndef _MINIX
+# undef _MINIX
+#endif
+/* Enable general extensions on NetBSD.
+   Enable NetBSD compatibility extensions on Minix.  */
+#ifndef _NETBSD_SOURCE
+# undef _NETBSD_SOURCE
+#endif
+/* Enable OpenBSD compatibility extensions on NetBSD.
+   Oddly enough, this does nothing on OpenBSD.  */
+#ifndef _OPENBSD_SOURCE
+# undef _OPENBSD_SOURCE
+#endif
+/* Define to 1 if needed for POSIX-compatible behavior.  */
+#ifndef _POSIX_SOURCE
+# undef _POSIX_SOURCE
+#endif
+/* Define to 2 if needed for POSIX-compatible behavior.  */
+#ifndef _POSIX_1_SOURCE
+# undef _POSIX_1_SOURCE
+#endif
+/* Enable POSIX-compatible threading on Solaris.  */
 #ifndef _POSIX_PTHREAD_SEMANTICS
 # undef _POSIX_PTHREAD_SEMANTICS
 #endif
+/* Enable extensions specified by ISO/IEC TS 18661-5:2014.  */
+#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-1:2014.  */
+#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+# undef __STDC_WANT_IEC_60559_BFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-2:2015.  */
+#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
+# undef __STDC_WANT_IEC_60559_DFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-4:2015.  */
+#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
+# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-3:2015.  */
+#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
+# undef __STDC_WANT_IEC_60559_TYPES_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TR 24731-2:2010.  */
+#ifndef __STDC_WANT_LIB_EXT2__
+# undef __STDC_WANT_LIB_EXT2__
+#endif
+/* Enable extensions specified by ISO/IEC 24747:2009.  */
+#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
+# undef __STDC_WANT_MATH_SPEC_FUNCS__
+#endif
 /* Enable extensions on HP NonStop.  */
 #ifndef _TANDEM_SOURCE
 # undef _TANDEM_SOURCE
 #endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
+/* Enable X/Open extensions.  Define to 500 only if necessary
+   to make mbstate_t available.  */
+#ifndef _XOPEN_SOURCE
+# undef _XOPEN_SOURCE
 #endif
 
 
 # endif
 #endif
 
-/* Enable large inode numbers on Mac OS X 10.5.  */
-#ifndef _DARWIN_USE_64_BIT_INODE
-# define _DARWIN_USE_64_BIT_INODE 1
-#endif
-
 /* Number of bits in a file offset, on hosts where this is settable. */
 #undef _FILE_OFFSET_BITS
 
 /* Define for large files, on AIX-style hosts. */
 #undef _LARGE_FILES
 
-/* Define to 1 if on MINIX. */
-#undef _MINIX
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
-   this defined. */
-#undef _POSIX_1_SOURCE
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-#undef _POSIX_SOURCE
-
 /* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
    <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
    #define below would cause a syntax error. */
 /* Define to `long int' if <sys/types.h> does not define. */
 #undef off_t
 
-/* Define to `int' if <sys/types.h> does not define. */
+/* Define as a signed integer type capable of holding a process identifier. */
 #undef pid_t
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
index 6d789f7..24e28be 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,11 +1,12 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for nghttp2 1.41.0.
+# Generated by GNU Autoconf 2.71 for nghttp2 1.46.0.
 #
 # Report bugs to <t-tujikawa@users.sourceforge.net>.
 #
 #
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
+# Inc.
 #
 #
 # This configure script is free software; the Free Software Foundation
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
-else
+else $as_nop
   case `(set -o) 2>/dev/null` in #(
   *posix*) :
     set -o posix ;; #(
@@ -33,46 +36,46 @@ esac
 fi
 
 
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
 as_nl='
 '
 export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-       expr "X$arg" : "X\\(.*\\)$as_nl";
-       arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
+IFS=" ""       $as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
 
 # The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
+if ${PATH_SEPARATOR+false} :; then
   PATH_SEPARATOR=:
   (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
     (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
@@ -81,13 +84,6 @@ if test "${PATH_SEPARATOR+set}" != set; then
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""       $as_nl"
-
 # Find who we are.  Look in the path if we contain no directory separator.
 as_myself=
 case $0 in #((
@@ -96,8 +92,12 @@ case $0 in #((
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
   done
 IFS=$as_save_IFS
 
@@ -109,30 +109,10 @@ if test "x$as_myself" = x; then
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
   exit 1
 fi
 
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 # Use a proper internal environment variable to ensure we don't fall
   # into an infinite loop, continuously re-executing ourselves.
@@ -154,20 +134,22 @@ esac
 exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
 # Admittedly, this is quite paranoid, since all the known shells bail
 # out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
   fi
   # We don't want this to propagate to other subprocesses.
           { _as_can_reexec=; unset _as_can_reexec;}
 if test "x$CONFIG_SHELL" = x; then
-  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  as_bourne_compatible="as_nop=:
+if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '\${1+\"\$@\"}'='\"\$@\"'
   setopt NO_GLOB_SUBST
-else
+else \$as_nop
   case \`(set -o) 2>/dev/null\` in #(
   *posix*) :
     set -o posix ;; #(
@@ -187,18 +169,20 @@ as_fn_success || { exitcode=1; echo as_fn_success failed.; }
 as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
 as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
 as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+if ( set x; as_fn_ret_success y && test x = \"\$1\" )
+then :
 
-else
+else \$as_nop
   exitcode=1; echo positional parameters were not saved.
 fi
 test x\$exitcode = x0 || exit 1
+blah=\$(echo \$(echo blah))
+test x\"\$blah\" = xblah || exit 1
 test -x / || exit 1"
   as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
   as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
   eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
   test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1
 
   test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
     ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
@@ -206,31 +190,40 @@ test \$(( 1 + 1 )) = 2 || exit 1
     ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
     PATH=/empty FPATH=/empty; export PATH FPATH
     test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
-      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
-  if (eval "$as_required") 2>/dev/null; then :
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null
+then :
   as_have_required=yes
-else
+else $as_nop
   as_have_required=no
 fi
-  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
+then :
 
-else
+else $as_nop
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 as_found=false
 for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
   as_found=:
   case $as_dir in #(
         /*)
           for as_base in sh bash ksh sh5; do
             # Try only shells that exist, to save several forks.
-            as_shell=$as_dir/$as_base
+            as_shell=$as_dir$as_base
             if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-                   { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+                   as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
   CONFIG_SHELL=$as_shell as_have_required=yes
-                  if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+                  if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
+then :
   break 2
 fi
 fi
@@ -238,14 +231,21 @@ fi
        esac
   as_found=false
 done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
-             { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
-  CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
 IFS=$as_save_IFS
+if $as_found
+then :
+
+else $as_nop
+  if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+             as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi
+fi
 
 
-      if test "x$CONFIG_SHELL" != x; then :
+      if test "x$CONFIG_SHELL" != x
+then :
   export CONFIG_SHELL
              # We cannot yet assume a decent shell, so we have to provide a
 # neutralization value for shells without unset; and this also
@@ -263,18 +263,19 @@ esac
 exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
 # Admittedly, this is quite paranoid, since all the known shells bail
 # out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
 exit 255
 fi
 
-    if test x$as_have_required = xno; then :
-  $as_echo "$0: This script requires a shell more modern than all"
-  $as_echo "$0: the shells that I found on your system."
-  if test x${ZSH_VERSION+set} = xset ; then
-    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
-    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+    if test x$as_have_required = xno
+then :
+  printf "%s\n" "$0: This script requires a shell more modern than all"
+  printf "%s\n" "$0: the shells that I found on your system."
+  if test ${ZSH_VERSION+y} ; then
+    printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
   else
-    $as_echo "$0: Please tell bug-autoconf@gnu.org and
+    printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and
 $0: t-tujikawa@users.sourceforge.net about your system,
 $0: including any error possibly output before this
 $0: message. Then install a modern shell, or manually run
@@ -302,6 +303,7 @@ as_fn_unset ()
 }
 as_unset=as_fn_unset
 
+
 # as_fn_set_status STATUS
 # -----------------------
 # Set $? to STATUS, without forking.
@@ -319,6 +321,14 @@ as_fn_exit ()
   as_fn_set_status $1
   exit $1
 } # as_fn_exit
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
 
 # as_fn_mkdir_p
 # -------------
@@ -333,7 +343,7 @@ as_fn_mkdir_p ()
     as_dirs=
     while :; do
       case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
       *) as_qdir=$as_dir;;
       esac
       as_dirs="'$as_qdir' $as_dirs"
@@ -342,7 +352,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$as_dir" : 'X\(//\)[^/]' \| \
         X"$as_dir" : 'X\(//\)$' \| \
         X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
+printf "%s\n" X"$as_dir" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -381,12 +391,13 @@ as_fn_executable_p ()
 # advantage of any shell optimizations that allow amortized linear growth over
 # repeated appends, instead of the typical quadratic growth present in naive
 # implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
   eval 'as_fn_append ()
   {
     eval $1+=\$2
   }'
-else
+else $as_nop
   as_fn_append ()
   {
     eval $1=\$$1\$2
@@ -398,18 +409,27 @@ fi # as_fn_append
 # Perform arithmetic evaluation on the ARGs, and store the result in the
 # global $as_val. Take advantage of shells that can avoid forks. The arguments
 # must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
   eval 'as_fn_arith ()
   {
     as_val=$(( $* ))
   }'
-else
+else $as_nop
   as_fn_arith ()
   {
     as_val=`expr "$@" || test $? -eq 1`
   }
 fi # as_fn_arith
 
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
 
 # as_fn_error STATUS ERROR [LINENO LOG_FD]
 # ----------------------------------------
@@ -421,9 +441,9 @@ as_fn_error ()
   as_status=$1; test $as_status -eq 0 && as_status=1
   if test "$4"; then
     as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $2" >&2
+  printf "%s\n" "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -450,7 +470,7 @@ as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         X"$0" : 'X\(//\)$' \| \
         X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
+printf "%s\n" X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
            s//\1/
            q
@@ -494,7 +514,7 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
       s/-\n.*//
     ' >$as_me.lineno &&
   chmod +x "$as_me.lineno" ||
-    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+    { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
   # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
   # already done that, so ensure we don't try to do so again and fall
@@ -508,6 +528,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
   exit
 }
 
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
 ECHO_C= ECHO_N= ECHO_T=
 case `echo -n x` in #(((((
 -n*)
@@ -521,6 +545,13 @@ case `echo -n x` in #(((((
   ECHO_N='-n';;
 esac
 
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
+
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
@@ -590,47 +621,44 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='nghttp2'
 PACKAGE_TARNAME='nghttp2'
-PACKAGE_VERSION='1.41.0'
-PACKAGE_STRING='nghttp2 1.41.0'
+PACKAGE_VERSION='1.46.0'
+PACKAGE_STRING='nghttp2 1.46.0'
 PACKAGE_BUGREPORT='t-tujikawa@users.sourceforge.net'
 PACKAGE_URL=''
 
 # Factoring default headers for most tests.
 ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
+#include <stddef.h>
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
 #endif
-#ifdef STDC_HEADERS
+#ifdef HAVE_STDLIB_H
 # include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
 #endif
 #ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-#  include <memory.h>
-# endif
 # include <string.h>
 #endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
 #ifdef HAVE_INTTYPES_H
 # include <inttypes.h>
 #endif
 #ifdef HAVE_STDINT_H
 # include <stdint.h>
 #endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif"
 
+ac_header_c_list=
+ac_func_c_list=
 ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
@@ -662,6 +690,8 @@ ENABLE_ASIO_LIB_FALSE
 ENABLE_ASIO_LIB_TRUE
 ENABLE_HPACK_TOOLS_FALSE
 ENABLE_HPACK_TOOLS_TRUE
+ENABLE_HTTP3_FALSE
+ENABLE_HTTP3_TRUE
 ENABLE_APP_FALSE
 ENABLE_APP_TRUE
 BOOST_THREAD_LIB
@@ -669,7 +699,6 @@ BOOST_SYSTEM_LIB
 BOOST_ASIO_LIB
 BOOST_LDFLAGS
 BOOST_CPPFLAGS
-JEMALLOC_LIBS
 HAVE_LIBXML2_FALSE
 HAVE_LIBXML2_TRUE
 LIBXML2_LIBS
@@ -680,24 +709,37 @@ JANSSON_LIBS
 JANSSON_CFLAGS
 LIBEVENT_OPENSSL_LIBS
 LIBEVENT_OPENSSL_CFLAGS
+HAVE_LIBBPF_FALSE
+HAVE_LIBBPF_TRUE
+EXTRABPFCFLAGS
+LIBBPF_LIBS
+LIBBPF_CFLAGS
+LIBNGHTTP3_LIBS
+LIBNGHTTP3_CFLAGS
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS
+LIBNGTCP2_LIBS
+LIBNGTCP2_CFLAGS
 LIBCARES_LIBS
 LIBCARES_CFLAGS
 OPENSSL_LIBS
 OPENSSL_CFLAGS
-LIBEV_CFLAGS
-LIBEV_LIBS
 HAVE_CUNIT_FALSE
 HAVE_CUNIT_TRUE
 CUNIT_LIBS
 CUNIT_CFLAGS
 ZLIB_LIBS
 ZLIB_CFLAGS
+EXTRA_DEFS
 CXX1XCXXFLAGS
 HAVE_CXX14
 PYTHON_EXTRA_LDFLAGS
 PYTHON_EXTRA_LIBS
+PYTHON_PLATFORM_SITE_PKG
 PYTHON_SITE_PKG
-PYTHON_LDFLAGS
+PYTHON_LIBS
 PYTHON_CPPFLAGS
 pkgpyexecdir
 pyexecdir
@@ -711,6 +753,7 @@ PYTHON
 PKG_CONFIG_LIBDIR
 PKG_CONFIG_PATH
 PKG_CONFIG
+CPP
 am__fastdepCXX_FALSE
 am__fastdepCXX_TRUE
 CXXDEPMODE
@@ -718,6 +761,12 @@ CXXCPP
 ac_ct_CXX
 CXXFLAGS
 CXX
+BPFCFLAGS
+LIBTOOL_LDFLAGS
+JEMALLOC_LIBS
+JEMALLOC_CFLAGS
+LIBEV_LIBS
+LIBEV_CFLAGS
 CYTHON
 PACKAGE_VERSION_NUM
 LT_AGE
@@ -727,6 +776,9 @@ AM_BACKSLASH
 AM_DEFAULT_VERBOSITY
 AM_DEFAULT_V
 AM_V
+CSCOPE
+ETAGS
+CTAGS
 am__fastdepCC_FALSE
 am__fastdepCC_TRUE
 CCDEPMODE
@@ -781,6 +833,8 @@ ac_ct_DUMPBIN
 DUMPBIN
 LD
 FGREP
+EGREP
+GREP
 SED
 host_os
 host_vendor
@@ -791,9 +845,6 @@ build_vendor
 build_cpu
 build
 LIBTOOL
-EGREP
-GREP
-CPP
 OBJEXT
 EXEEXT
 ac_ct_CC
@@ -864,12 +915,25 @@ enable_examples
 enable_python_bindings
 enable_failmalloc
 enable_lib_only
+enable_http3
 with_libxml2
+with_jansson
+with_zlib
+with_libevent_openssl
+with_libcares
+with_openssl
+with_libev
+with_cunit
 with_jemalloc
 with_systemd
 with_mruby
 with_neverbleed
 with_cython
+with_libngtcp2
+with_libnghttp3
+with_libbpf
+with_python_prefix
+with_python_exec_prefix
 with_boost
 with_boost_libdir
 with_boost_asio
@@ -886,13 +950,19 @@ CFLAGS
 LDFLAGS
 LIBS
 CPPFLAGS
-CPP
 LT_SYS_LIBRARY_PATH
 CYTHON
+LIBEV_CFLAGS
+LIBEV_LIBS
+JEMALLOC_CFLAGS
+JEMALLOC_LIBS
+LIBTOOL_LDFLAGS
+BPFCFLAGS
 CXX
 CXXFLAGS
 CCC
 CXXCPP
+CPP
 PKG_CONFIG
 PKG_CONFIG_PATH
 PKG_CONFIG_LIBDIR
@@ -906,6 +976,16 @@ OPENSSL_CFLAGS
 OPENSSL_LIBS
 LIBCARES_CFLAGS
 LIBCARES_LIBS
+LIBNGTCP2_CFLAGS
+LIBNGTCP2_LIBS
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS
+LIBNGHTTP3_CFLAGS
+LIBNGHTTP3_LIBS
+LIBBPF_CFLAGS
+LIBBPF_LIBS
 LIBEVENT_OPENSSL_CFLAGS
 LIBEVENT_OPENSSL_LIBS
 JANSSON_CFLAGS
@@ -982,8 +1062,6 @@ do
   *)    ac_optarg=yes ;;
   esac
 
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
   case $ac_dashdash$ac_option in
   --)
     ac_dashdash=yes ;;
@@ -1024,9 +1102,9 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "enable_$ac_useropt"
@@ -1050,9 +1128,9 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "enable_$ac_useropt"
@@ -1263,9 +1341,9 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "with_$ac_useropt"
@@ -1279,9 +1357,9 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "with_$ac_useropt"
@@ -1325,9 +1403,9 @@ Try \`$0 --help' for more information"
 
   *)
     # FIXME: should be removed in autoconf 3.0.
-    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+      printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
     : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
 
@@ -1343,7 +1421,7 @@ if test -n "$ac_unrecognized_opts"; then
   case $enable_option_checking in
     no) ;;
     fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
-    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+    *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
   esac
 fi
 
@@ -1407,7 +1485,7 @@ $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$as_myself" : 'X\(//\)[^/]' \| \
         X"$as_myself" : 'X\(//\)$' \| \
         X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
+printf "%s\n" X"$as_myself" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -1464,7 +1542,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures nghttp2 1.41.0 to adapt to many kinds of systems.
+\`configure' configures nghttp2 1.46.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1536,7 +1614,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of nghttp2 1.41.0:";;
+     short | recursive ) echo "Configuration of nghttp2 1.46.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1569,6 +1647,8 @@ Optional Features:
   --enable-lib-only       Build libnghttp2 only. This is a short hand for
                           --disable-app --disable-examples
                           --disable-hpack-tools --disable-python-bindings
+  --enable-http3          (EXPERIMENTAL) Enable HTTP/3. This requires ngtcp2,
+                          nghttp3, and a custom OpenSSL.
   --disable-assert        turn off assertions
   --disable-largefile     omit support for large files
 
@@ -1584,11 +1664,24 @@ Optional Packages:
   --with-sysroot[=DIR]    Search for dependent libraries within DIR (or the
                           compiler's sysroot if not specified).
   --with-libxml2          Use libxml2 [default=check]
+  --with-jansson          Use jansson [default=check]
+  --with-zlib             Use zlib [default=check]
+  --with-libevent-openssl Use libevent_openssl [default=check]
+  --with-libcares         Use libc-ares [default=check]
+  --with-openssl          Use openssl [default=check]
+  --with-libev            Use libev [default=check]
+  --with-cunit            Use cunit [default=check]
   --with-jemalloc         Use jemalloc [default=check]
   --with-systemd          Enable systemd support in nghttpx [default=check]
   --with-mruby            Use mruby [default=no]
   --with-neverbleed       Use neverbleed [default=no]
   --with-cython=PATH      Use cython in given PATH
+  --with-libngtcp2        Use libngtcp2 [default=check]
+  --with-libnghttp3       Use libnghttp3 [default=check]
+  --with-libbpf           Use libbpf [default=no]
+  --with-python_prefix    override the default PYTHON_PREFIX
+  --with-python_exec_prefix
+                          override the default PYTHON_EXEC_PREFIX
   --with-boost[=ARG]      use Boost library from a standard location
                           (ARG=yes), from the specified location (ARG=<path>),
                           or disable it (ARG=no) [ARG=yes]
@@ -1619,13 +1712,23 @@ Some influential environment variables:
   LIBS        libraries to pass to the linker, e.g. -l<library>
   CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
               you have headers in a nonstandard directory <include dir>
-  CPP         C preprocessor
   LT_SYS_LIBRARY_PATH
               User-defined run-time library search path.
   CYTHON      the Cython executable
+  LIBEV_CFLAGS
+              C compiler flags for libev, skipping any checks
+  LIBEV_LIBS  linker flags for libev, skipping any checks
+  JEMALLOC_CFLAGS
+              C compiler flags for jemalloc, skipping any checks
+  JEMALLOC_LIBS
+              linker flags for jemalloc, skipping any checks
+  LIBTOOL_LDFLAGS
+              libtool specific flags (e.g., -static-libtool-libs)
+  BPFCFLAGS   C compiler flags for bpf program
   CXX         C++ compiler command
   CXXFLAGS    C++ compiler flags
   CXXCPP      C++ preprocessor
+  CPP         C preprocessor
   PKG_CONFIG  path to pkg-config utility
   PKG_CONFIG_PATH
               directories to add to pkg-config's search path
@@ -1649,6 +1752,28 @@ Some influential environment variables:
               C compiler flags for LIBCARES, overriding pkg-config
   LIBCARES_LIBS
               linker flags for LIBCARES, overriding pkg-config
+  LIBNGTCP2_CFLAGS
+              C compiler flags for LIBNGTCP2, overriding pkg-config
+  LIBNGTCP2_LIBS
+              linker flags for LIBNGTCP2, overriding pkg-config
+  LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS
+              C compiler flags for LIBNGTCP2_CRYPTO_OPENSSL, overriding
+              pkg-config
+  LIBNGTCP2_CRYPTO_OPENSSL_LIBS
+              linker flags for LIBNGTCP2_CRYPTO_OPENSSL, overriding pkg-config
+  LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS
+              C compiler flags for LIBNGTCP2_CRYPTO_BORINGSSL, overriding
+              pkg-config
+  LIBNGTCP2_CRYPTO_BORINGSSL_LIBS
+              linker flags for LIBNGTCP2_CRYPTO_BORINGSSL, overriding
+              pkg-config
+  LIBNGHTTP3_CFLAGS
+              C compiler flags for LIBNGHTTP3, overriding pkg-config
+  LIBNGHTTP3_LIBS
+              linker flags for LIBNGHTTP3, overriding pkg-config
+  LIBBPF_CFLAGS
+              C compiler flags for LIBBPF, overriding pkg-config
+  LIBBPF_LIBS linker flags for LIBBPF, overriding pkg-config
   LIBEVENT_OPENSSL_CFLAGS
               C compiler flags for LIBEVENT_OPENSSL, overriding pkg-config
   LIBEVENT_OPENSSL_LIBS
@@ -1685,9 +1810,9 @@ if test "$ac_init_help" = "recursive"; then
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -1715,7 +1840,8 @@ esac
 ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
     cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
+    # Check for configure.gnu first; this name is used for a wrapper for
+    # Metaconfig's "Configure" on case-insensitive file systems.
     if test -f "$ac_srcdir/configure.gnu"; then
       echo &&
       $SHELL "$ac_srcdir/configure.gnu" --help=recursive
@@ -1723,7 +1849,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
       echo &&
       $SHELL "$ac_srcdir/configure" --help=recursive
     else
-      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+      printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi || ac_status=$?
     cd "$ac_pwd" || { ac_status=$?; break; }
   done
@@ -1732,10 +1858,10 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-nghttp2 configure 1.41.0
-generated by GNU Autoconf 2.69
+nghttp2 configure 1.46.0
+generated by GNU Autoconf 2.71
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -1752,14 +1878,14 @@ fi
 ac_fn_c_try_compile ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
+  rm -f conftest.$ac_objext conftest.beam
   if { { ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -1767,14 +1893,15 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
+       } && test -s conftest.$ac_objext
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
        ac_retval=1
@@ -1784,176 +1911,6 @@ fi
 
 } # ac_fn_c_try_compile
 
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } > conftest.i && {
-        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-    ac_retval=1
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_cpp
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_header_compiler=yes
-else
-  ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  ac_header_preproc=yes
-else
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
-  yes:no: )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-  no:yes:* )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ----------------------------------------------- ##
-## Report this to t-tujikawa@users.sourceforge.net ##
-## ----------------------------------------------- ##"
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_mongrel
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: program exited with status $ac_status" >&5
-       $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=$ac_status
-fi
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
-
 # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
 # -------------------------------------------------------
 # Tests whether HEADER exists and can be compiled using the include files in
@@ -1961,26 +1918,28 @@ fi
 ac_fn_c_check_header_compile ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 #include <$2>
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "$3=yes"
-else
+else $as_nop
   eval "$3=no"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_header_compile
@@ -1991,14 +1950,14 @@ $as_echo "$ac_res" >&6; }
 ac_fn_c_try_link ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
+  rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
   if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -2006,17 +1965,18 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
        } && test -s conftest$ac_exeext && {
         test "$cross_compiling" = yes ||
         test -x conftest$ac_exeext
-       }; then :
+       }
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
        ac_retval=1
@@ -2037,11 +1997,12 @@ fi
 ac_fn_c_check_func ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 /* Define $2 to an innocuous variant, in case <limits.h> declares $2.
@@ -2049,16 +2010,9 @@ else
 #define $2 innocuous_$2
 
 /* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $2 (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+   which can conflict with char $2 (); below.  */
 
+#include <limits.h>
 #undef $2
 
 /* Override any GCC internal prototype to avoid an error.
@@ -2076,24 +2030,25 @@ choke me
 #endif
 
 int
-main ()
+main (void)
 {
 return $2 ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$3=yes"
-else
+else $as_nop
   eval "$3=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 fi
 eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_func
@@ -2104,14 +2059,14 @@ $as_echo "$ac_res" >&6; }
 ac_fn_cxx_try_compile ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
+  rm -f conftest.$ac_objext conftest.beam
   if { { ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -2119,14 +2074,15 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
         test -z "$ac_cxx_werror_flag" ||
         test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
+       } && test -s conftest.$ac_objext
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
        ac_retval=1
@@ -2148,7 +2104,7 @@ case "(($ac_try" in
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -2156,14 +2112,15 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } > conftest.i && {
         test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
         test ! -s conftest.err
-       }; then :
+       }
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
     ac_retval=1
@@ -2179,14 +2136,14 @@ fi
 ac_fn_cxx_try_link ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
+  rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
   if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -2194,17 +2151,18 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
         test -z "$ac_cxx_werror_flag" ||
         test ! -s conftest.err
        } && test -s conftest$ac_exeext && {
         test "$cross_compiling" = yes ||
         test -x conftest$ac_exeext
-       }; then :
+       }
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
        ac_retval=1
@@ -2219,6 +2177,44 @@ fi
 
 } # ac_fn_cxx_try_link
 
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
 # ac_fn_c_check_type LINENO TYPE VAR INCLUDES
 # -------------------------------------------
 # Tests whether TYPE exists after having included INCLUDES, setting cache
@@ -2226,17 +2222,18 @@ fi
 ac_fn_c_check_type ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   eval "$3=no"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 if (sizeof ($2))
         return 0;
@@ -2244,12 +2241,13 @@ if (sizeof ($2))
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 if (sizeof (($2)))
            return 0;
@@ -2257,18 +2255,19 @@ if (sizeof (($2)))
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
 
-else
+else $as_nop
   eval "$3=yes"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_type
@@ -2280,11 +2279,12 @@ $as_echo "$ac_res" >&6; }
 ac_fn_c_find_uintX_t ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
-$as_echo_n "checking for uint$2_t... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
+printf %s "checking for uint$2_t... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   eval "$3=no"
      # Order is important - never check a type that is potentially smaller
      # than half of the expected target width.
@@ -2294,7 +2294,7 @@ else
 /* end confdefs.h.  */
 $ac_includes_default
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)];
 test_array [0] = 0;
@@ -2304,7 +2304,8 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   case $ac_type in #(
   uint$2_t) :
     eval "$3=yes" ;; #(
@@ -2312,17 +2313,18 @@ if ac_fn_c_try_compile "$LINENO"; then :
     eval "$3=\$ac_type" ;;
 esac
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       if eval test \"x\$"$3"\" = x"no"; then :
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+       if eval test \"x\$"$3"\" = x"no"
+then :
 
-else
+else $as_nop
   break
 fi
      done
 fi
 eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_find_uintX_t
@@ -2334,11 +2336,12 @@ $as_echo "$ac_res" >&6; }
 ac_fn_c_find_intX_t ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
-$as_echo_n "checking for int$2_t... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
+printf %s "checking for int$2_t... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   eval "$3=no"
      # Order is important - never check a type that is potentially smaller
      # than half of the expected target width.
@@ -2349,7 +2352,7 @@ else
 $ac_includes_default
             enum { N = $2 / 2 - 1 };
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
 test_array [0] = 0;
@@ -2359,13 +2362,14 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
                enum { N = $2 / 2 - 1 };
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
                 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
@@ -2376,9 +2380,10 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
 
-else
+else $as_nop
   case $ac_type in #(
   int$2_t) :
     eval "$3=yes" ;; #(
@@ -2386,40 +2391,85 @@ else
     eval "$3=\$ac_type" ;;
 esac
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       if eval test \"x\$"$3"\" = x"no"; then :
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+       if eval test \"x\$"$3"\" = x"no"
+then :
 
-else
+else $as_nop
   break
 fi
      done
 fi
 eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_find_intX_t
 
-# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
-# ----------------------------------------------------
-# Tries to find if the field MEMBER exists in type AGGR, after including
-# INCLUDES, setting cache variable VAR accordingly.
-ac_fn_c_check_member ()
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
+# executables *can* be run.
+ac_fn_c_try_run ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
-$as_echo_n "checking for $2.$3... " >&6; }
-if eval \${$4+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: program exited with status $ac_status" >&5
+       printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+printf %s "checking for $2.$3... " >&6; }
+if eval test \${$4+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 $5
 int
-main ()
+main (void)
 {
 static $2 ac_aggr;
 if (ac_aggr.$3)
@@ -2428,14 +2478,15 @@ return 0;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "$4=yes"
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $5
 int
-main ()
+main (void)
 {
 static $2 ac_aggr;
 if (sizeof ac_aggr.$3)
@@ -2444,18 +2495,19 @@ return 0;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "$4=yes"
-else
+else $as_nop
   eval "$4=no"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 eval ac_res=\$$4
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_member
@@ -2474,7 +2526,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !(($2) >= 0)];
 test_array [0] = 0;
@@ -2484,14 +2536,15 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_lo=0 ac_mid=0
   while :; do
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
 test_array [0] = 0;
@@ -2501,9 +2554,10 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_hi=$ac_mid; break
-else
+else $as_nop
   as_fn_arith $ac_mid + 1 && ac_lo=$as_val
                        if test $ac_lo -le $ac_mid; then
                          ac_lo= ac_hi=
@@ -2511,14 +2565,14 @@ else
                        fi
                        as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   done
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !(($2) < 0)];
 test_array [0] = 0;
@@ -2528,14 +2582,15 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_hi=-1 ac_mid=-1
   while :; do
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !(($2) >= $ac_mid)];
 test_array [0] = 0;
@@ -2545,9 +2600,10 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_lo=$ac_mid; break
-else
+else $as_nop
   as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
                        if test $ac_mid -le $ac_hi; then
                          ac_lo= ac_hi=
@@ -2555,14 +2611,14 @@ else
                        fi
                        as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   done
-else
+else $as_nop
   ac_lo= ac_hi=
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 # Binary search between lo and hi bounds.
 while test "x$ac_lo" != "x$ac_hi"; do
   as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
@@ -2570,7 +2626,7 @@ while test "x$ac_lo" != "x$ac_hi"; do
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
 test_array [0] = 0;
@@ -2580,12 +2636,13 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_hi=$ac_mid
-else
+else $as_nop
   as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 done
 case $ac_lo in #((
 ?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
@@ -2595,12 +2652,12 @@ esac
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
-static long int longval () { return $2; }
-static unsigned long int ulongval () { return $2; }
+static long int longval (void) { return $2; }
+static unsigned long int ulongval (void) { return $2; }
 #include <stdio.h>
 #include <stdlib.h>
 int
-main ()
+main (void)
 {
 
   FILE *f = fopen ("conftest.val", "w");
@@ -2628,9 +2685,10 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   echo >>conftest.val; read $3 <conftest.val; ac_retval=0
-else
+else $as_nop
   ac_retval=1
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -2643,25 +2701,28 @@ rm -f conftest.val
 
 } # ac_fn_c_compute_int
 
-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
-# ---------------------------------------------
+# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR
+# ------------------------------------------------------------------
 # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
-# accordingly.
-ac_fn_c_check_decl ()
+# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR.
+ac_fn_check_decl ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   as_decl_name=`echo $2|sed 's/ *(.*//'`
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+printf %s "checking whether $as_decl_name is declared... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
-$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  eval ac_save_FLAGS=\$$6
+  as_fn_append $6 " $5"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 #ifndef $as_decl_name
 #ifdef __cplusplus
@@ -2675,27 +2736,50 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "$3=yes"
-else
+else $as_nop
   eval "$3=no"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+  eval $6=\$ac_save_FLAGS
+
 fi
 eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
-} # ac_fn_c_check_decl
+} # ac_fn_check_decl
+ac_configure_args_raw=
+for ac_arg
+do
+  case $ac_arg in
+  *\'*)
+    ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  as_fn_append ac_configure_args_raw " '$ac_arg'"
+done
+
+case $ac_configure_args_raw in
+  *$as_nl*)
+    ac_safe_unquote= ;;
+  *)
+    ac_unsafe_z='|&;<>()$`\\"*?[ ''    ' # This string ends in space, tab.
+    ac_unsafe_a="$ac_unsafe_z#~"
+    ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
+    ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
+esac
+
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by nghttp2 $as_me 1.41.0, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
+It was created by nghttp2 $as_me 1.46.0, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
 
-  $ $0 $@
+  $ $0$ac_configure_args_raw
 
 _ACEOF
 exec 5>>config.log
@@ -2728,8 +2812,12 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    $as_echo "PATH: $as_dir"
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    printf "%s\n" "PATH: $as_dir"
   done
 IFS=$as_save_IFS
 
@@ -2764,7 +2852,7 @@ do
     | -silent | --silent | --silen | --sile | --sil)
       continue ;;
     *\'*)
-      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     case $ac_pass in
     1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
@@ -2799,11 +2887,13 @@ done
 # WARNING: Use '\'' to represent an apostrophe within the trap.
 # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
 trap 'exit_status=$?
+  # Sanitize IFS.
+  IFS=" ""     $as_nl"
   # Save into config.log some information that might help in debugging.
   {
     echo
 
-    $as_echo "## ---------------- ##
+    printf "%s\n" "## ---------------- ##
 ## Cache variables. ##
 ## ---------------- ##"
     echo
@@ -2814,8 +2904,8 @@ trap 'exit_status=$?
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
@@ -2839,7 +2929,7 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
 )
     echo
 
-    $as_echo "## ----------------- ##
+    printf "%s\n" "## ----------------- ##
 ## Output variables. ##
 ## ----------------- ##"
     echo
@@ -2847,14 +2937,14 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
     do
       eval ac_val=\$$ac_var
       case $ac_val in
-      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
       esac
-      $as_echo "$ac_var='\''$ac_val'\''"
+      printf "%s\n" "$ac_var='\''$ac_val'\''"
     done | sort
     echo
 
     if test -n "$ac_subst_files"; then
-      $as_echo "## ------------------- ##
+      printf "%s\n" "## ------------------- ##
 ## File substitutions. ##
 ## ------------------- ##"
       echo
@@ -2862,15 +2952,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       do
        eval ac_val=\$$ac_var
        case $ac_val in
-       *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+       *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
        esac
-       $as_echo "$ac_var='\''$ac_val'\''"
+       printf "%s\n" "$ac_var='\''$ac_val'\''"
       done | sort
       echo
     fi
 
     if test -s confdefs.h; then
-      $as_echo "## ----------- ##
+      printf "%s\n" "## ----------- ##
 ## confdefs.h. ##
 ## ----------- ##"
       echo
@@ -2878,8 +2968,8 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       echo
     fi
     test "$ac_signal" != 0 &&
-      $as_echo "$as_me: caught signal $ac_signal"
-    $as_echo "$as_me: exit $exit_status"
+      printf "%s\n" "$as_me: caught signal $ac_signal"
+    printf "%s\n" "$as_me: exit $exit_status"
   } >&5
   rm -f core *.core core.conftest.* &&
     rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
@@ -2893,63 +2983,48 @@ ac_signal=0
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
 rm -f -r conftest* confdefs.h
 
-$as_echo "/* confdefs.h */" > confdefs.h
+printf "%s\n" "/* confdefs.h */" > confdefs.h
 
 # Predefined preprocessor variables.
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
+printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
+printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
+printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
+printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
+printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
+printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
 
 
 # Let the site file select an alternate cache file if it wants to.
 # Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  # We do not want a PATH search for config.site.
-  case $CONFIG_SITE in #((
-    -*)  ac_site_file1=./$CONFIG_SITE;;
-    */*) ac_site_file1=$CONFIG_SITE;;
-    *)   ac_site_file1=./$CONFIG_SITE;;
-  esac
+  ac_site_files="$CONFIG_SITE"
 elif test "x$prefix" != xNONE; then
-  ac_site_file1=$prefix/share/config.site
-  ac_site_file2=$prefix/etc/config.site
+  ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
 else
-  ac_site_file1=$ac_default_prefix/share/config.site
-  ac_site_file2=$ac_default_prefix/etc/config.site
+  ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
 fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+
+for ac_site_file in $ac_site_files
 do
-  test "x$ac_site_file" = xNONE && continue
-  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+  case $ac_site_file in #(
+  */*) :
+     ;; #(
+  *) :
+    ac_site_file=./$ac_site_file ;;
+esac
+  if test -f "$ac_site_file" && test -r "$ac_site_file"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
     . "$ac_site_file" \
-      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+      || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "failed to load site script $ac_site_file
 See \`config.log' for more details" "$LINENO" 5; }
   fi
@@ -2959,963 +3034,717 @@ if test -r "$cache_file"; then
   # Some versions of bash will fail to source /dev/null (special files
   # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
   if test /dev/null != "$cache_file" && test -f "$cache_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
       [\\/]* | ?:[\\/]* ) . "$cache_file";;
       *)                      . "./$cache_file";;
     esac
   fi
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
   >$cache_file
 fi
 
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
-  eval ac_old_set=\$ac_cv_env_${ac_var}_set
-  eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val=\$ac_cv_env_${ac_var}_value
-  eval ac_new_val=\$ac_env_${ac_var}_value
-  case $ac_old_set,$ac_new_set in
-    set,)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,set)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,);;
-    *)
-      if test "x$ac_old_val" != "x$ac_new_val"; then
-       # differences in whitespace do not lead to failure.
-       ac_old_val_w=`echo x $ac_old_val`
-       ac_new_val_w=`echo x $ac_new_val`
-       if test "$ac_old_val_w" != "$ac_new_val_w"; then
-         { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-         ac_cache_corrupted=:
-       else
-         { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
-         eval $ac_var=\$ac_old_val
-       fi
-       { $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
-$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
-       { $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
-$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
-      fi;;
-  esac
-  # Pass precious variables to config.status.
-  if test "$ac_new_set" = set; then
-    case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
-    *) ac_arg=$ac_var=$ac_new_val ;;
-    esac
-    case " $ac_configure_args " in
-      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
-      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
-    esac
-  fi
-done
-if $ac_cache_corrupted; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
+# Test code for whether the C compiler supports C89 (global declarations)
+ac_c_conftest_c89_globals='
+/* Does the compiler advertise C89 conformance?
+   Do not test the value of __STDC__, because some compilers set it to 0
+   while being otherwise adequately conformant. */
+#if !defined __STDC__
+# error "Compiler does not advertise C89 conformance"
+#endif
 
+#include <stddef.h>
+#include <stdarg.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */
+struct buf { int x; };
+struct buf * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
 
-ac_aux_dir=
-for ac_dir in . "$srcdir"/.; do
-  if test -f "$ac_dir/install-sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f "$ac_dir/install.sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f "$ac_dir/shtool"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  as_fn_error $? "cannot find install-sh, install.sh, or shtool in . \"$srcdir\"/." "$LINENO" 5
-fi
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not \xHH hex character constants.
+   These do not provoke an error unfortunately, instead are silently treated
+   as an "x".  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously \x00 != x always comes out true, for an
+   array size at least.  It is necessary to write \x00 == 0 to get something
+   that is true only with -std.  */
+int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
 
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) '\''x'\''
+int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
 
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
+               int, int);'
 
+# Test code for whether the C compiler supports C89 (body of main).
+ac_c_conftest_c89_main='
+ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
+'
 
-ac_config_headers="$ac_config_headers config.h"
+# Test code for whether the C compiler supports C99 (global declarations)
+ac_c_conftest_c99_globals='
+// Does the compiler advertise C99 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
+# error "Compiler does not advertise C99 conformance"
+#endif
 
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+#include <stdbool.h>
+extern int puts (const char *);
+extern int printf (const char *, ...);
+extern int dprintf (int, const char *, ...);
+extern void *malloc (size_t);
+
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+// dprintf is used instead of fprintf to avoid needing to declare
+// FILE and stderr.
+#define debug(...) dprintf (2, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  #error "your preprocessor is broken"
+#endif
+#if BIG_OK
+#else
+  #error "your preprocessor is broken"
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
 
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
 
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
 
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+typedef const char *ccp;
 
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+static inline int
+test_restrict (ccp restrict text)
+{
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
+    continue;
+  return 0;
+}
 
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-else
-  CC="$ac_cv_prog_CC"
-fi
+// Check varargs and va_copy.
+static bool
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
 
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+  const char *str = "";
+  int number = 0;
+  float fnumber = 0;
 
+  while (*format)
+    {
+      switch (*format++)
+       {
+       case '\''s'\'': // string
+         str = va_arg (args_copy, const char *);
+         break;
+       case '\''d'\'': // int
+         number = va_arg (args_copy, int);
+         break;
+       case '\''f'\'': // float
+         fnumber = va_arg (args_copy, double);
+         break;
+       default:
+         break;
+       }
+    }
+  va_end (args_copy);
+  va_end (args);
 
-  fi
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+  return *str && number && fnumber;
+}
+'
 
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+# Test code for whether the C compiler supports C99 (body of main).
+ac_c_conftest_c99_main='
+  // Check bool.
+  _Bool success = false;
+  success |= (argc != 0);
+
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
+
+  // Check varargs.
+  success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
+  test_varargs_macros ();
+
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
+
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
+
+  ni.number = 58;
+
+  int dynamic_array[ni.number];
+  dynamic_array[0] = argv[0][0];
+  dynamic_array[ni.number - 1] = 543;
+
+  // work around unused variable warnings
+  ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
+        || dynamic_array[ni.number - 1] != 543);
+'
 
+# Test code for whether the C compiler supports C11 (global declarations)
+ac_c_conftest_c11_globals='
+// Does the compiler advertise C11 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
+# error "Compiler does not advertise C11 conformance"
+#endif
 
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+// Check _Alignas.
+char _Alignas (double) aligned_as_double;
+char _Alignas (0) no_special_alignment;
+extern char aligned_as_int;
+char _Alignas (0) _Alignas (int) aligned_as_int;
 
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+// Check _Alignof.
+enum
+{
+  int_alignment = _Alignof (int),
+  int_array_alignment = _Alignof (int[100]),
+  char_alignment = _Alignof (char)
+};
+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
 
+// Check _Noreturn.
+int _Noreturn does_not_return (void) { for (;;) continue; }
 
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+// Check _Static_assert.
+struct test_static_assert
+{
+  int x;
+  _Static_assert (sizeof (int) <= sizeof (long int),
+                  "_Static_assert does not work in struct");
+  long int y;
+};
 
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+// Check UTF-8 literals.
+#define u8 syntax error!
+char const utf8_literal[] = u8"happens to be ASCII" "another string";
 
+// Check duplicate typedefs.
+typedef long *long_ptr;
+typedef long int *long_ptr;
+typedef long_ptr long_ptr;
 
-  test -n "$ac_ct_CC" && break
-done
+// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
+struct anonymous
+{
+  union {
+    struct { int i; int j; };
+    struct { int k; long int l; } w;
+  };
+  int m;
+} v1;
+'
 
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-fi
+# Test code for whether the C compiler supports C11 (body of main).
+ac_c_conftest_c11_main='
+  _Static_assert ((offsetof (struct anonymous, i)
+                  == offsetof (struct anonymous, w.k)),
+                 "Anonymous union alignment botch");
+  v1.i = 2;
+  v1.w.k = 5;
+  ok |= v1.i != 5;
+'
 
-fi
+# Test code for whether the C compiler supports C11 (complete).
+ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+${ac_c_conftest_c11_globals}
 
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  ${ac_c_conftest_c11_main}
+  return ok;
+}
+"
 
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
+# Test code for whether the C compiler supports C99 (complete).
+ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
 
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
-  { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    sed '10a\
-... rest of stderr output deleted ...
-         10q' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-  fi
-  rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-done
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  return ok;
+}
+"
 
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+# Test code for whether the C compiler supports C89 (complete).
+ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
 
 int
-main ()
+main (int argc, char **argv)
 {
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  return ok;
+}
+"
 
-  ;
-  return 0;
+as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
+as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
+as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
+as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
+as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
+as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
+as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
+as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
+as_fn_append ac_header_c_list " wchar.h wchar_h HAVE_WCHAR_H"
+as_fn_append ac_header_c_list " minix/config.h minix_config_h HAVE_MINIX_CONFIG_H"
+# Test code for whether the C++ compiler supports C++98 (global declarations)
+ac_cxx_conftest_cxx98_globals='
+// Does the compiler advertise C++98 conformance?
+#if !defined __cplusplus || __cplusplus < 199711L
+# error "Compiler does not advertise C++98 conformance"
+#endif
+
+// These inclusions are to reject old compilers that
+// lack the unsuffixed header files.
+#include <cstdlib>
+#include <exception>
+
+// <cassert> and <cstring> are *not* freestanding headers in C++98.
+extern void assert (int);
+namespace std {
+  extern int strcmp (const char *, const char *);
 }
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
 
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+// Namespaces, exceptions, and templates were all added after "C++ 2.0".
+using std::exception;
+using std::strcmp;
 
-ac_rmfiles=
-for ac_file in $ac_files
-do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
-    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
-  esac
-done
-rm -f $ac_rmfiles
+namespace {
 
-if { { ac_try="$ac_link_default"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link_default") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile.  We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
-       ;;
-    [ab].out )
-       # We found the default executable, but exeext='' is most
-       # certainly right.
-       break;;
-    *.* )
-       if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
-       then :; else
-          ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-       fi
-       # We set ac_cv_exeext here because the later test for it is not
-       # safe: cross compilers may not add the suffix if given an `-o'
-       # argument, so we may need to know it at that point already.
-       # Even if this section looks crufty: it has the advantage of
-       # actually working.
-       break;;
-    * )
-       break;;
-  esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
+void test_exception_syntax()
+{
+  try {
+    throw "test";
+  } catch (const char *s) {
+    // Extra parentheses suppress a warning when building autoconf itself,
+    // due to lint rules shared with more typical C programs.
+    assert (!(strcmp) (s, "test"));
+  }
+}
 
-else
-  ac_file=''
-fi
-if test -z "$ac_file"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+template <typename T> struct test_template
+{
+  T const val;
+  explicit test_template(T t) : val(t) {}
+  template <typename U> T add(U u) { return static_cast<T>(u) + val; }
+};
 
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-ac_exeext=$ac_cv_exeext
+} // anonymous namespace
+'
 
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-         break;;
-    * ) break;;
-  esac
-done
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdio.h>
-int
-main ()
+# Test code for whether the C++ compiler supports C++98 (body of main)
+ac_cxx_conftest_cxx98_main='
+  assert (argc);
+  assert (! argv[0]);
 {
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;
-
-  ;
-  return 0;
+  test_exception_syntax ();
+  test_template<double> tt (2.0);
+  assert (tt.add (4) == 6.0);
+  assert (true && !false);
 }
-_ACEOF
-ac_clean_files="$ac_clean_files conftest.out"
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-if test "$cross_compiling" != yes; then
-  { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-  if { ac_try='./conftest$ac_cv_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-       cross_compiling=yes
-    else
-       { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
-    fi
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
+'
 
-rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+# Test code for whether the C++ compiler supports C++11 (global declarations)
+ac_cxx_conftest_cxx11_globals='
+// Does the compiler advertise C++ 2011 conformance?
+#if !defined __cplusplus || __cplusplus < 201103L
+# error "Compiler does not advertise C++11 conformance"
+#endif
 
-int
-main ()
+namespace cxx11test
 {
+  constexpr int get_val() { return 20; }
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compile") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  for ac_file in conftest.o conftest.obj conftest.*; do
-  test -f "$ac_file" || continue;
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+  struct testinit
+  {
+    int i;
+    double d;
+  };
 
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
+  class delegate
+  {
+  public:
+    delegate(int n) : n(n) {}
+    delegate(): delegate(2354) {}
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_compiler_gnu=yes
-else
-  ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
+    virtual int getval() { return this->n; };
+  protected:
+    int n;
+  };
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
-  GCC=yes
-else
-  GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+  class overridden : public delegate
+  {
+  public:
+    overridden(int n): delegate(n) {}
+    virtual int getval() override final { return this->n * 2; }
+  };
 
-int
-main ()
-{
+  class nocopy
+  {
+  public:
+    nocopy(int i): i(i) {}
+    nocopy() = default;
+    nocopy(const nocopy&) = delete;
+    nocopy & operator=(const nocopy&) = delete;
+  private:
+    int i;
+  };
+
+  // for testing lambda expressions
+  template <typename Ret, typename Fn> Ret eval(Fn f, Ret v)
+  {
+    return f(v);
+  }
 
-  ;
-  return 0;
+  // for testing variadic templates and trailing return types
+  template <typename V> auto sum(V first) -> V
+  {
+    return first;
+  }
+  template <typename V, typename... Args> auto sum(V first, Args... rest) -> V
+  {
+    return first + sum(rest...);
+  }
 }
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-else
-  CFLAGS=""
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+'
 
-int
-main ()
+# Test code for whether the C++ compiler supports C++11 (body of main)
+ac_cxx_conftest_cxx11_main='
 {
+  // Test auto and decltype
+  auto a1 = 6538;
+  auto a2 = 48573953.4;
+  auto a3 = "String literal";
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  ac_c_werror_flag=$ac_save_c_werror_flag
-        CFLAGS="-g"
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+  int total = 0;
+  for (auto i = a3; *i; ++i) { total += *i; }
 
-int
-main ()
+  decltype(a2) a4 = 34895.034;
+}
 {
-
-  ;
-  return 0;
+  // Test constexpr
+  short sa[cxx11test::get_val()] = { 0 };
 }
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
 {
-  return p[i];
+  // Test initializer lists
+  cxx11test::testinit il = { 4323, 435234.23544 };
 }
-static char *f (char * (*g) (char **, int), char **p, ...)
 {
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
+  // Test range-based for
+  int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3,
+                 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
+  for (auto &x : array) { x += 23; }
 }
+{
+  // Test lambda expressions
+  using cxx11test::eval;
+  assert (eval ([](int x) { return x*2; }, 21) == 42);
+  double d = 2.0;
+  assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0);
+  assert (d == 5.0);
+  assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0);
+  assert (d == 5.0);
+}
+{
+  // Test use of variadic templates
+  using cxx11test::sum;
+  auto a = sum(1);
+  auto b = sum(1, 2);
+  auto c = sum(1.0, 2.0, 3.0);
+}
+{
+  // Test constructor delegation
+  cxx11test::delegate d1;
+  cxx11test::delegate d2();
+  cxx11test::delegate d3(45);
+}
+{
+  // Test override and final
+  cxx11test::overridden o1(55464);
+}
+{
+  // Test nullptr
+  char *c = nullptr;
+}
+{
+  // Test template brackets
+  test_template<::test_template<int>> v(test_template<int>(12));
+}
+{
+  // Unicode literals
+  char const *utf8 = u8"UTF-8 string \u2500";
+  char16_t const *utf16 = u"UTF-8 string \u2500";
+  char32_t const *utf32 = U"UTF-32 string \u2500";
+}
+'
 
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+# Test code for whether the C compiler supports C++11 (complete).
+ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals}
+${ac_cxx_conftest_cxx11_globals}
 
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_cxx_conftest_cxx98_main}
+  ${ac_cxx_conftest_cxx11_main}
+  return ok;
+}
+"
 
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
+# Test code for whether the C compiler supports C++98 (complete).
+ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals}
 int
-main ()
+main (int argc, char **argv)
 {
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
+  int ok = 0;
+  ${ac_cxx_conftest_cxx98_main}
+  return ok;
 }
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
+"
 
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
+as_fn_append ac_header_c_list " vfork.h vfork_h HAVE_VFORK_H"
+as_fn_append ac_func_c_list " fork HAVE_FORK"
+as_fn_append ac_func_c_list " vfork HAVE_VFORK"
 
-fi
+# Auxiliary files required by this configure script.
+ac_aux_files="missing install-sh config.guess config.sub ltmain.sh compile"
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+# Locations in which to look for auxiliary files.
+ac_aux_dir_candidates="${srcdir}/."
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
-$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
-if ${am_cv_prog_cc_c_o+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
+# Search for a directory containing all of the required auxiliary files,
+# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates.
+# If we don't find one directory that contains all the files we need,
+# we report the set of missing files from the *first* directory in
+# $ac_aux_dir_candidates and give up.
+ac_missing_aux_files=""
+ac_first_candidate=:
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in $ac_aux_dir_candidates
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+  as_found=:
 
-  ;
-  return 0;
-}
-_ACEOF
-  # Make sure it works both with $CC and with simple cc.
-  # Following AC_PROG_CC_C_O, we do the test twice because some
-  # compilers refuse to overwrite an existing .o file with -o,
-  # though they will create one.
-  am_cv_prog_cc_c_o=yes
-  for am_i in 1 2; do
-    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
-   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } \
-         && test -f conftest2.$ac_objext; then
-      : OK
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}:  trying $as_dir" >&5
+  ac_aux_dir_found=yes
+  ac_install_sh=
+  for ac_aux in $ac_aux_files
+  do
+    # As a special case, if "install-sh" is required, that requirement
+    # can be satisfied by any of "install-sh", "install.sh", or "shtool",
+    # and $ac_install_sh is set appropriately for whichever one is found.
+    if test x"$ac_aux" = x"install-sh"
+    then
+      if test -f "${as_dir}install-sh"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install-sh found" >&5
+        ac_install_sh="${as_dir}install-sh -c"
+      elif test -f "${as_dir}install.sh"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install.sh found" >&5
+        ac_install_sh="${as_dir}install.sh -c"
+      elif test -f "${as_dir}shtool"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}shtool found" >&5
+        ac_install_sh="${as_dir}shtool install -c"
+      else
+        ac_aux_dir_found=no
+        if $ac_first_candidate; then
+          ac_missing_aux_files="${ac_missing_aux_files} install-sh"
+        else
+          break
+        fi
+      fi
     else
-      am_cv_prog_cc_c_o=no
-      break
+      if test -f "${as_dir}${ac_aux}"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}${ac_aux} found" >&5
+      else
+        ac_aux_dir_found=no
+        if $ac_first_candidate; then
+          ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}"
+        else
+          break
+        fi
+      fi
     fi
   done
-  rm -f core conftest*
-  unset am_i
+  if test "$ac_aux_dir_found" = yes; then
+    ac_aux_dir="$as_dir"
+    break
+  fi
+  ac_first_candidate=false
+
+  as_found=false
+done
+IFS=$as_save_IFS
+if $as_found
+then :
+
+else $as_nop
+  as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
-$as_echo "$am_cv_prog_cc_c_o" >&6; }
-if test "$am_cv_prog_cc_c_o" != yes; then
-   # Losing compiler, so override with the script.
-   # FIXME: It is wrong to rewrite CC.
-   # But if we don't then we get into trouble of one sort or another.
-   # A longer-term fix would be to have automake use am__CC in this case,
-   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
-   CC="$am_aux_dir/compile $CC"
+
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+if test -f "${ac_aux_dir}config.guess"; then
+  ac_config_guess="$SHELL ${ac_aux_dir}config.guess"
+fi
+if test -f "${ac_aux_dir}config.sub"; then
+  ac_config_sub="$SHELL ${ac_aux_dir}config.sub"
+fi
+if test -f "$ac_aux_dir/configure"; then
+  ac_configure="$SHELL ${ac_aux_dir}configure"
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       # differences in whitespace do not lead to failure.
+       ac_old_val_w=`echo x $ac_old_val`
+       ac_new_val_w=`echo x $ac_new_val`
+       if test "$ac_old_val_w" != "$ac_new_val_w"; then
+         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+         ac_cache_corrupted=:
+       else
+         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+         eval $ac_var=\$ac_old_val
+       fi
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+printf "%s\n" "$as_me:   former value:  \`$ac_old_val'" >&2;}
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+printf "%s\n" "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
+           and start over" "$LINENO" 5
 fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3924,616 +3753,1398 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+
+
+
+
+
+
+
+
+
+
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
-  $as_echo_n "(cached) " >&6
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
 do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-else
-  # Broken: fails on valid input.
-continue
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-  break
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-    done
-    ac_cv_prog_CPP=$CPP
 
 fi
-  CPP=$ac_cv_prog_CPP
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
-  ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
 do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-  # Broken: fails on valid input.
-continue
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
 else
-  # Passes both tests.
-ac_preproc_ok=:
-break
+  CC="$ac_cv_prog_CC"
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
 
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
-  $as_echo_n "(cached) " >&6
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  if test -z "$GREP"; then
-  ac_path_GREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in grep ggrep; do
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_GREP" || continue
-# Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_GREP_found && break 3
-    done
-  done
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
   done
 IFS=$as_save_IFS
-  if test -z "$ac_cv_path_GREP"; then
-    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
   fi
-else
-  ac_cv_path_GREP=$GREP
 fi
-
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
-  $as_echo_n "(cached) " >&6
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     if test -z "$EGREP"; then
-  ac_path_EGREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in egrep; do
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_EGREP" || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_EGREP_found && break 3
-    done
-  done
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
   done
 IFS=$as_save_IFS
-  if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
-else
-  ac_cv_path_EGREP=$EGREP
-fi
 
-   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
-  $as_echo_n "(cached) " >&6
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_stdc=yes
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-  ac_cv_header_stdc=no
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <string.h>
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then :
+  test -n "$ac_ct_CC" && break
+done
 
-else
-  ac_cv_header_stdc=no
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
 fi
-rm -f conftest*
 
 fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
+set dummy ${ac_tool_prefix}clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then :
-
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  ac_cv_header_stdc=no
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
-rm -f conftest*
 
-fi
 
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then :
-  :
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "clang", so it can be a program name with args.
+set dummy clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-                  (('a' <= (c) && (c) <= 'i') \
-                    || ('j' <= (c) && (c) <= 'r') \
-                    || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-       || toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-
 fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
 
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
 
 fi
 
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-                 inttypes.h stdint.h unistd.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
 
-fi
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
 
+# Provide some information about the compiler.
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion -version; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
 done
 
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
+int
+main (void)
+{
 
-  ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
-if test "x$ac_cv_header_minix_config_h" = xyes; then :
-  MINIX=yes
-else
-  MINIX=
-fi
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+printf %s "checking whether the C compiler works... " >&6; }
+ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
 
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
 
-  if test "$MINIX" = yes; then
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
 
-$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
+       then :; else
+          ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       fi
+       # We set ac_cv_exeext here because the later test for it is not
+       # safe: cross compilers may not add the suffix if given an `-o'
+       # argument, so we may need to know it at that point already.
+       # Even if this section looks crufty: it has the advantage of
+       # actually working.
+       break;;
+    * )
+       break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
 
+else $as_nop
+  ac_file=''
+fi
+if test -z "$ac_file"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+printf %s "checking for C compiler default output file name... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+printf "%s\n" "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
 
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+printf %s "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         break;;
+    * ) break;;
+  esac
+done
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+printf "%s\n" "$ac_cv_exeext" >&6; }
 
-$as_echo "#define _MINIX 1" >>confdefs.h
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main (void)
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
 
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+printf %s "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
   fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+printf "%s\n" "$cross_compiling" >&6; }
 
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
-$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
-if ${ac_cv_safe_to_define___extensions__+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+printf %s "checking for suffix of object files... " >&6; }
+if test ${ac_cv_objext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-#         define __EXTENSIONS__ 1
-          $ac_includes_default
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_safe_to_define___extensions__=yes
-else
-  ac_cv_safe_to_define___extensions__=no
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
-$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
-  test $ac_cv_safe_to_define___extensions__ = yes &&
-    $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+printf "%s\n" "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
+printf %s "checking whether the compiler supports GNU C... " >&6; }
+if test ${ac_cv_c_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
-  $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+int
+main (void)
+{
+#ifndef __GNUC__
+       choke me
+#endif
 
-  $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_compiler_gnu=yes
+else $as_nop
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
-  $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-  $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+y}
+ac_save_CFLAGS=$CFLAGS
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+printf %s "checking whether $CC accepts -g... " >&6; }
+if test ${ac_cv_prog_cc_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
+int
+main (void)
+{
 
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_g=yes
+else $as_nop
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
+int
+main (void)
+{
 
-case `pwd` in
-  *\ * | *\    *)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
-$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
-esac
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
 
+else $as_nop
+  ac_c_werror_flag=$ac_save_c_werror_flag
+        CFLAGS="-g"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
+int
+main (void)
+{
 
-macro_version='2.4.6'
-macro_revision='2.4.6'
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
+if test $ac_test_CFLAGS; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+ac_prog_cc_stdc=no
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
+printf %s "checking for $CC option to enable C11 features... " >&6; }
+if test ${ac_cv_prog_cc_c11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c11=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c11_program
+_ACEOF
+for ac_arg in '' -std=gnu11
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c11=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c11" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
 
+if test "x$ac_cv_prog_cc_c11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
+     CC="$CC $ac_cv_prog_cc_c11"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
+  ac_prog_cc_stdc=c11
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
+printf %s "checking for $CC option to enable C99 features... " >&6; }
+if test ${ac_cv_prog_cc_c99+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c99_program
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
 
+if test "x$ac_cv_prog_cc_c99" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c99" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
+     CC="$CC $ac_cv_prog_cc_c99"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+  ac_prog_cc_stdc=c99
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
+printf %s "checking for $CC option to enable C89 features... " >&6; }
+if test ${ac_cv_prog_cc_c89+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c89_program
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
 
+if test "x$ac_cv_prog_cc_c89" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c89" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
+     CC="$CC $ac_cv_prog_cc_c89"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+  ac_prog_cc_stdc=c89
+fi
+fi
 
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+printf %s "checking whether $CC understands -c and -o together... " >&6; }
+if test ${am_cv_prog_cc_c_o+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
+int
+main (void)
+{
 
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+printf "%s\n" "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
+ac_header= ac_cache=
+for ac_item in $ac_header_c_list
+do
+  if test $ac_cache; then
+    ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
+    if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
+      printf "%s\n" "#define $ac_item 1" >> confdefs.h
+    fi
+    ac_header= ac_cache=
+  elif test $ac_header; then
+    ac_cache=$ac_item
+  else
+    ac_header=$ac_item
+  fi
+done
 
 
-ltmain=$ac_aux_dir/ltmain.sh
 
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
-  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if ${ac_cv_build+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
-  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
-  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
-  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if ${ac_cv_host+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "x$host_alias" = x; then
-  ac_cv_host=$ac_cv_build
-else
-  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
-    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
-fi
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
+then :
 
+printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
 
-# Backslashify metacharacters that are still active within
-# double-quoted strings.
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+fi
 
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\(["`\\]\)/\\\1/g'
 
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
 
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
 
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
 
-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
-$as_echo_n "checking how to print strings... " >&6; }
-# Test print first, because it will be a builtin if present.
-if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
-   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
-  ECHO='print -r --'
-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
-  ECHO='printf %s\n'
-else
-  # Use this function as a fallback that always works.
-  func_fallback_echo ()
-  {
-    eval 'cat <<_LTECHO_EOF
-$1
-_LTECHO_EOF'
-  }
-  ECHO='func_fallback_echo'
-fi
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+printf %s "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if test ${ac_cv_safe_to_define___extensions__+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
-# func_echo_all arg...
-# Invoke $ECHO with all args, space-separated.
-func_echo_all ()
+#         define __EXTENSIONS__ 1
+          $ac_includes_default
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_safe_to_define___extensions__=yes
+else $as_nop
+  ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+printf "%s\n" "$ac_cv_safe_to_define___extensions__" >&6; }
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5
+printf %s "checking whether _XOPEN_SOURCE should be defined... " >&6; }
+if test ${ac_cv_should_define__xopen_source+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_should_define__xopen_source=no
+    if test $ac_cv_header_wchar_h = yes
+then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+          #include <wchar.h>
+          mbstate_t x;
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+            #define _XOPEN_SOURCE 500
+            #include <wchar.h>
+            mbstate_t x;
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_should_define__xopen_source=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5
+printf "%s\n" "$ac_cv_should_define__xopen_source" >&6; }
+
+  printf "%s\n" "#define _ALL_SOURCE 1" >>confdefs.h
+
+  printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h
+
+  printf "%s\n" "#define _GNU_SOURCE 1" >>confdefs.h
+
+  printf "%s\n" "#define _HPUX_ALT_XOPEN_SOCKET_API 1" >>confdefs.h
+
+  printf "%s\n" "#define _NETBSD_SOURCE 1" >>confdefs.h
+
+  printf "%s\n" "#define _OPENBSD_SOURCE 1" >>confdefs.h
+
+  printf "%s\n" "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_IEC_60559_BFP_EXT__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_IEC_60559_DFP_EXT__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_LIB_EXT2__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_MATH_SPEC_FUNCS__ 1" >>confdefs.h
+
+  printf "%s\n" "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+  if test $ac_cv_header_minix_config_h = yes
+then :
+  MINIX=yes
+    printf "%s\n" "#define _MINIX 1" >>confdefs.h
+
+    printf "%s\n" "#define _POSIX_SOURCE 1" >>confdefs.h
+
+    printf "%s\n" "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+else $as_nop
+  MINIX=
+fi
+  if test $ac_cv_safe_to_define___extensions__ = yes
+then :
+  printf "%s\n" "#define __EXTENSIONS__ 1" >>confdefs.h
+
+fi
+  if test $ac_cv_should_define__xopen_source = yes
+then :
+  printf "%s\n" "#define _XOPEN_SOURCE 500" >>confdefs.h
+
+fi
+
+
+
+case `pwd` in
+  *\ * | *\    *)
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.6'
+macro_revision='2.4.6'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+
+  # Make sure we can run config.sub.
+$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+printf %s "checking build system type... " >&6; }
+if test ${ac_cv_build+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+printf "%s\n" "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+printf %s "checking host system type... " >&6; }
+if test ${ac_cv_host+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+printf "%s\n" "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+printf %s "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
 {
     $ECHO ""
 }
 
 case $ECHO in
-  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
-$as_echo "printf" >&6; } ;;
-  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
-$as_echo "print -r" >&6; } ;;
-  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
-$as_echo "cat" >&6; } ;;
+  printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+printf "%s\n" "printf" >&6; } ;;
+  print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+printf "%s\n" "print -r" >&6; } ;;
+  *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+printf "%s\n" "cat" >&6; } ;;
 esac
 
 
@@ -4549,11 +5160,12 @@ esac
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
-$as_echo_n "checking for a sed that does not truncate output... " >&6; }
-if ${ac_cv_path_SED+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+printf %s "checking for a sed that does not truncate output... " >&6; }
+if test ${ac_cv_path_SED+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
             ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
      for ac_i in 1 2 3 4 5 6 7; do
        ac_script="$ac_script$as_nl$ac_script"
@@ -4567,10 +5179,15 @@ else
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in sed gsed; do
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in sed gsed
+   do
     for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      ac_path_SED="$as_dir$ac_prog$ac_exec_ext"
       as_fn_executable_p "$ac_path_SED" || continue
 # Check for GNU ac_path_SED and select it if it is found.
   # Check for GNU $ac_path_SED
@@ -4579,13 +5196,13 @@ case `"$ac_path_SED" --version 2>&1` in
   ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
 *)
   ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
+  printf %s 0123456789 >"conftest.in"
   while :
   do
     cat "conftest.in" "conftest.in" >"conftest.tmp"
     mv "conftest.tmp" "conftest.in"
     cp "conftest.in" "conftest.nl"
-    $as_echo '' >> "conftest.nl"
+    printf "%s\n" '' >> "conftest.nl"
     "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
     diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
     as_fn_arith $ac_count + 1 && ac_count=$as_val
@@ -4613,8 +5230,8 @@ else
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
-$as_echo "$ac_cv_path_SED" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+printf "%s\n" "$ac_cv_path_SED" >&6; }
  SED="$ac_cv_path_SED"
   rm -f conftest.sed
 
@@ -4631,47 +5248,50 @@ Xsed="$SED -e 1s/^X//"
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
-$as_echo_n "checking for fgrep... " >&6; }
-if ${ac_cv_path_FGREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
-   then ac_cv_path_FGREP="$GREP -F"
-   else
-     if test -z "$FGREP"; then
-  ac_path_FGREP_found=false
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+printf %s "checking for grep that handles long lines and -e... " >&6; }
+if test ${ac_cv_path_GREP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
   # Loop through the user's path and test for each of PROGNAME-LIST
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in fgrep; do
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in grep ggrep
+   do
     for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_FGREP" || continue
-# Check for GNU ac_path_FGREP and select it if it is found.
-  # Check for GNU $ac_path_FGREP
-case `"$ac_path_FGREP" --version 2>&1` in
+      ac_path_GREP="$as_dir$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
 *GNU*)
-  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
 *)
   ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
+  printf %s 0123456789 >"conftest.in"
   while :
   do
     cat "conftest.in" "conftest.in" >"conftest.tmp"
     mv "conftest.tmp" "conftest.in"
     cp "conftest.in" "conftest.nl"
-    $as_echo 'FGREP' >> "conftest.nl"
-    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    printf "%s\n" 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
     diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
     as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
       # Best one so far, save it but keep looking for a better one
-      ac_cv_path_FGREP="$ac_path_FGREP"
-      ac_path_FGREP_max=$ac_count
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
     fi
     # 10*(2^10) chars as input seems more than enough
     test $ac_count -gt 10 && break
@@ -4679,60 +5299,206 @@ case `"$ac_path_FGREP" --version 2>&1` in
   rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
 esac
 
-      $ac_path_FGREP_found && break 3
+      $ac_path_GREP_found && break 3
     done
   done
   done
 IFS=$as_save_IFS
-  if test -z "$ac_cv_path_FGREP"; then
-    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
 else
-  ac_cv_path_FGREP=$FGREP
+  ac_cv_path_GREP=$GREP
 fi
 
-   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
-$as_echo "$ac_cv_path_FGREP" >&6; }
- FGREP="$ac_cv_path_FGREP"
-
-
-test -z "$GREP" && GREP=grep
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+printf "%s\n" "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
 
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
-  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
-else
-  with_gnu_ld=no
-fi
 
-ac_prog=ld
-if test yes = "$GCC"; then
-  # Check if gcc -print-prog-name=ld gives a path.
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
-$as_echo_n "checking for ld used by $CC... " >&6; }
-  case $host in
-  *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+printf %s "checking for egrep... " >&6; }
+if test ${ac_cv_path_EGREP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in egrep
+   do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  printf %s 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    printf "%s\n" 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+printf "%s\n" "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+printf %s "checking for fgrep... " >&6; }
+if test ${ac_cv_path_FGREP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in fgrep
+   do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  printf %s 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    printf "%s\n" 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+printf "%s\n" "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test ${with_gnu_ld+y}
+then :
+  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else $as_nop
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+printf %s "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return, which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -4758,15 +5524,16 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
     ;;
   esac
 elif test yes = "$with_gnu_ld"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
-$as_echo_n "checking for GNU ld... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+printf %s "checking for GNU ld... " >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
-$as_echo_n "checking for non-GNU ld... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+printf %s "checking for non-GNU ld... " >&6; }
 fi
-if ${lt_cv_path_LD+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+if test ${lt_cv_path_LD+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -z "$LD"; then
   lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
@@ -4795,18 +5562,19 @@ fi
 
 LD=$lt_cv_path_LD
 if test -n "$LD"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
-$as_echo "$LD" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+printf "%s\n" "$LD" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
-$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if ${lt_cv_prog_gnu_ld+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+printf %s "checking if the linker ($LD) is GNU ld... " >&6; }
+if test ${lt_cv_prog_gnu_ld+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   # I'd rather use --version here, but apparently some GNU lds only accept -v.
 case `$LD -v 2>&1 </dev/null` in
 *GNU* | *'with BFD'*)
@@ -4817,8 +5585,8 @@ case `$LD -v 2>&1 </dev/null` in
   ;;
 esac
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
-$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; }
 with_gnu_ld=$lt_cv_prog_gnu_ld
 
 
@@ -4829,11 +5597,12 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
-$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
-if ${lt_cv_path_NM+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if test ${lt_cv_path_NM+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$NM"; then
   # Let the user override the test.
   lt_cv_path_NM=$NM
@@ -4883,8 +5652,8 @@ else
   : ${lt_cv_path_NM=no}
 fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
-$as_echo "$lt_cv_path_NM" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+printf "%s\n" "$lt_cv_path_NM" >&6; }
 if test no != "$lt_cv_path_NM"; then
   NM=$lt_cv_path_NM
 else
@@ -4897,11 +5666,12 @@ else
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_DUMPBIN+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_DUMPBIN+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$DUMPBIN"; then
   ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
 else
@@ -4909,11 +5679,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -4924,11 +5698,11 @@ fi
 fi
 DUMPBIN=$ac_cv_prog_DUMPBIN
 if test -n "$DUMPBIN"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
-$as_echo "$DUMPBIN" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+printf "%s\n" "$DUMPBIN" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -4941,11 +5715,12 @@ if test -z "$DUMPBIN"; then
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_DUMPBIN+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_DUMPBIN"; then
   ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
 else
@@ -4953,11 +5728,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -4968,11 +5747,11 @@ fi
 fi
 ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
 if test -n "$ac_ct_DUMPBIN"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
-$as_echo "$ac_ct_DUMPBIN" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+printf "%s\n" "$ac_ct_DUMPBIN" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -4984,8 +5763,8 @@ done
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     DUMPBIN=$ac_ct_DUMPBIN
@@ -5013,11 +5792,12 @@ test -z "$NM" && NM=nm
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
-$as_echo_n "checking the name lister ($NM) interface... " >&6; }
-if ${lt_cv_nm_interface+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+printf %s "checking the name lister ($NM) interface... " >&6; }
+if test ${lt_cv_nm_interface+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
   (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
@@ -5033,26 +5813,27 @@ else
   fi
   rm -f conftest*
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
-$as_echo "$lt_cv_nm_interface" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+printf "%s\n" "$lt_cv_nm_interface" >&6; }
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
-$as_echo_n "checking whether ln -s works... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+printf %s "checking whether ln -s works... " >&6; }
 LN_S=$as_ln_s
 if test "$LN_S" = "ln -s"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
-$as_echo "no, using $LN_S" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+printf "%s\n" "no, using $LN_S" >&6; }
 fi
 
 # find the maximum length of command line arguments
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
-$as_echo_n "checking the maximum length of command line arguments... " >&6; }
-if ${lt_cv_sys_max_cmd_len+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+printf %s "checking the maximum length of command line arguments... " >&6; }
+if test ${lt_cv_sys_max_cmd_len+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
     i=0
   teststring=ABCD
 
@@ -5179,11 +5960,11 @@ else
 fi
 
 if test -n "$lt_cv_sys_max_cmd_len"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
-$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
-$as_echo "none" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
+printf "%s\n" "none" >&6; }
 fi
 max_cmd_len=$lt_cv_sys_max_cmd_len
 
@@ -5227,11 +6008,12 @@ esac
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
-$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
-if ${lt_cv_to_host_file_cmd+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+printf %s "checking how to convert $build file names to $host format... " >&6; }
+if test ${lt_cv_to_host_file_cmd+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   case $host in
   *-*-mingw* )
     case $build in
@@ -5267,18 +6049,19 @@ esac
 fi
 
 to_host_file_cmd=$lt_cv_to_host_file_cmd
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
-$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; }
 
 
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
-$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
-if ${lt_cv_to_tool_file_cmd+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+printf %s "checking how to convert $build file names to toolchain format... " >&6; }
+if test ${lt_cv_to_tool_file_cmd+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   #assume ordinary cross tools, or native build.
 lt_cv_to_tool_file_cmd=func_convert_file_noop
 case $host in
@@ -5294,22 +6077,23 @@ esac
 fi
 
 to_tool_file_cmd=$lt_cv_to_tool_file_cmd
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
-$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; }
 
 
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
-$as_echo_n "checking for $LD option to reload object files... " >&6; }
-if ${lt_cv_ld_reload_flag+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+printf %s "checking for $LD option to reload object files... " >&6; }
+if test ${lt_cv_ld_reload_flag+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_ld_reload_flag='-r'
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
-$as_echo "$lt_cv_ld_reload_flag" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+printf "%s\n" "$lt_cv_ld_reload_flag" >&6; }
 reload_flag=$lt_cv_ld_reload_flag
 case $reload_flag in
 "" | " "*) ;;
@@ -5342,11 +6126,12 @@ esac
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
 set dummy ${ac_tool_prefix}objdump; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_OBJDUMP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_OBJDUMP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$OBJDUMP"; then
   ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
 else
@@ -5354,11 +6139,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -5369,11 +6158,11 @@ fi
 fi
 OBJDUMP=$ac_cv_prog_OBJDUMP
 if test -n "$OBJDUMP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
-$as_echo "$OBJDUMP" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+printf "%s\n" "$OBJDUMP" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -5382,11 +6171,12 @@ if test -z "$ac_cv_prog_OBJDUMP"; then
   ac_ct_OBJDUMP=$OBJDUMP
   # Extract the first word of "objdump", so it can be a program name with args.
 set dummy objdump; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_OBJDUMP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_OBJDUMP"; then
   ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
 else
@@ -5394,11 +6184,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_OBJDUMP="objdump"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -5409,11 +6203,11 @@ fi
 fi
 ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
 if test -n "$ac_ct_OBJDUMP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
-$as_echo "$ac_ct_OBJDUMP" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+printf "%s\n" "$ac_ct_OBJDUMP" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_OBJDUMP" = x; then
@@ -5421,8 +6215,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     OBJDUMP=$ac_ct_OBJDUMP
@@ -5441,11 +6235,12 @@ test -z "$OBJDUMP" && OBJDUMP=objdump
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
-$as_echo_n "checking how to recognize dependent libraries... " >&6; }
-if ${lt_cv_deplibs_check_method+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+printf %s "checking how to recognize dependent libraries... " >&6; }
+if test ${lt_cv_deplibs_check_method+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_file_magic_cmd='$MAGIC_CMD'
 lt_cv_file_magic_test_file=
 lt_cv_deplibs_check_method='unknown'
@@ -5641,8 +6436,8 @@ os2*)
 esac
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
-$as_echo "$lt_cv_deplibs_check_method" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+printf "%s\n" "$lt_cv_deplibs_check_method" >&6; }
 
 file_magic_glob=
 want_nocaseglob=no
@@ -5686,11 +6481,12 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
 set dummy ${ac_tool_prefix}dlltool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_DLLTOOL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_DLLTOOL+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$DLLTOOL"; then
   ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
 else
@@ -5698,11 +6494,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -5713,11 +6513,11 @@ fi
 fi
 DLLTOOL=$ac_cv_prog_DLLTOOL
 if test -n "$DLLTOOL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
-$as_echo "$DLLTOOL" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+printf "%s\n" "$DLLTOOL" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -5726,11 +6526,12 @@ if test -z "$ac_cv_prog_DLLTOOL"; then
   ac_ct_DLLTOOL=$DLLTOOL
   # Extract the first word of "dlltool", so it can be a program name with args.
 set dummy dlltool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_DLLTOOL+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_DLLTOOL"; then
   ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
 else
@@ -5738,11 +6539,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_DLLTOOL="dlltool"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -5753,11 +6558,11 @@ fi
 fi
 ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
 if test -n "$ac_ct_DLLTOOL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
-$as_echo "$ac_ct_DLLTOOL" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+printf "%s\n" "$ac_ct_DLLTOOL" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_DLLTOOL" = x; then
@@ -5765,8 +6570,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     DLLTOOL=$ac_ct_DLLTOOL
@@ -5786,11 +6591,12 @@ test -z "$DLLTOOL" && DLLTOOL=dlltool
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
-$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
-if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+printf %s "checking how to associate runtime and link libraries... " >&6; }
+if test ${lt_cv_sharedlib_from_linklib_cmd+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_sharedlib_from_linklib_cmd='unknown'
 
 case $host_os in
@@ -5813,8 +6619,8 @@ cygwin* | mingw* | pw32* | cegcc*)
 esac
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
-$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
 sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
 test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
 
@@ -5829,11 +6635,12 @@ if test -n "$ac_tool_prefix"; then
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AR+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_AR+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$AR"; then
   ac_cv_prog_AR="$AR" # Let the user override the test.
 else
@@ -5841,11 +6648,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -5856,11 +6667,11 @@ fi
 fi
 AR=$ac_cv_prog_AR
 if test -n "$AR"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
-$as_echo "$AR" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+printf "%s\n" "$AR" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -5873,11 +6684,12 @@ if test -z "$AR"; then
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_AR+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_AR+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_AR"; then
   ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
 else
@@ -5885,11 +6697,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_AR="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -5900,11 +6716,11 @@ fi
 fi
 ac_ct_AR=$ac_cv_prog_ac_ct_AR
 if test -n "$ac_ct_AR"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
-$as_echo "$ac_ct_AR" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+printf "%s\n" "$ac_ct_AR" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -5916,8 +6732,8 @@ done
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     AR=$ac_ct_AR
@@ -5937,30 +6753,32 @@ fi
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
-$as_echo_n "checking for archiver @FILE support... " >&6; }
-if ${lt_cv_ar_at_file+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+printf %s "checking for archiver @FILE support... " >&6; }
+if test ${lt_cv_ar_at_file+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_ar_at_file=no
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   echo conftest.$ac_objext > conftest.lst
       lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
       { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
   (eval $lt_ar_try) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
       if test 0 -eq "$ac_status"; then
        # Ensure the archiver fails upon bogus file names.
@@ -5968,7 +6786,7 @@ if ac_fn_c_try_compile "$LINENO"; then :
        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
   (eval $lt_ar_try) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
        if test 0 -ne "$ac_status"; then
           lt_cv_ar_at_file=@
@@ -5977,11 +6795,11 @@ if ac_fn_c_try_compile "$LINENO"; then :
       rm -f conftest.* libconftest.a
 
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
-$as_echo "$lt_cv_ar_at_file" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+printf "%s\n" "$lt_cv_ar_at_file" >&6; }
 
 if test no = "$lt_cv_ar_at_file"; then
   archiver_list_spec=
@@ -5998,11 +6816,12 @@ fi
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
 set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_STRIP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_STRIP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$STRIP"; then
   ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
 else
@@ -6010,11 +6829,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_STRIP="${ac_tool_prefix}strip"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -6025,11 +6848,11 @@ fi
 fi
 STRIP=$ac_cv_prog_STRIP
 if test -n "$STRIP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
-$as_echo "$STRIP" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+printf "%s\n" "$STRIP" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -6038,11 +6861,12 @@ if test -z "$ac_cv_prog_STRIP"; then
   ac_ct_STRIP=$STRIP
   # Extract the first word of "strip", so it can be a program name with args.
 set dummy strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_STRIP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_STRIP"; then
   ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
 else
@@ -6050,11 +6874,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_STRIP="strip"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -6065,11 +6893,11 @@ fi
 fi
 ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
 if test -n "$ac_ct_STRIP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
-$as_echo "$ac_ct_STRIP" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+printf "%s\n" "$ac_ct_STRIP" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_STRIP" = x; then
@@ -6077,8 +6905,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     STRIP=$ac_ct_STRIP
@@ -6097,11 +6925,12 @@ test -z "$STRIP" && STRIP=:
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_RANLIB+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_RANLIB+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$RANLIB"; then
   ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
 else
@@ -6109,11 +6938,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -6124,11 +6957,11 @@ fi
 fi
 RANLIB=$ac_cv_prog_RANLIB
 if test -n "$RANLIB"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
-$as_echo "$RANLIB" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+printf "%s\n" "$RANLIB" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -6137,11 +6970,12 @@ if test -z "$ac_cv_prog_RANLIB"; then
   ac_ct_RANLIB=$RANLIB
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_RANLIB+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_RANLIB"; then
   ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
 else
@@ -6149,11 +6983,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_RANLIB="ranlib"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -6164,11 +7002,11 @@ fi
 fi
 ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
 if test -n "$ac_ct_RANLIB"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
-$as_echo "$ac_ct_RANLIB" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+printf "%s\n" "$ac_ct_RANLIB" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_RANLIB" = x; then
@@ -6176,8 +7014,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     RANLIB=$ac_ct_RANLIB
@@ -6241,11 +7079,12 @@ for ac_prog in gawk mawk nawk awk
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AWK+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_AWK+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$AWK"; then
   ac_cv_prog_AWK="$AWK" # Let the user override the test.
 else
@@ -6253,11 +7092,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_AWK="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -6268,11 +7111,11 @@ fi
 fi
 AWK=$ac_cv_prog_AWK
 if test -n "$AWK"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
-$as_echo "$AWK" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+printf "%s\n" "$AWK" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -6308,11 +7151,12 @@ compiler=$CC
 
 
 # Check for command to grab the raw symbol name followed by C symbol from nm.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
-$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
-if ${lt_cv_sys_global_symbol_pipe+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+printf %s "checking command to parse $NM output from $compiler object... " >&6; }
+if test ${lt_cv_sys_global_symbol_pipe+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
 # These are sane defaults that work on at least a few old systems.
 # [They come from Ultrix.  What could be older than Ultrix?!! ;)]
@@ -6464,7 +7308,7 @@ _LT_EOF
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
     # Now try to grab the symbols.
     nlist=conftest.nm
@@ -6537,7 +7381,7 @@ _LT_EOF
          if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && test -s conftest$ac_exeext; then
            pipe_works=yes
          fi
@@ -6572,11 +7416,11 @@ if test -z "$lt_cv_sys_global_symbol_pipe"; then
   lt_cv_sys_global_symbol_to_cdecl=
 fi
 if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
-$as_echo "failed" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+printf "%s\n" "failed" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
-$as_echo "ok" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+printf "%s\n" "ok" >&6; }
 fi
 
 # Response file support.
@@ -6622,13 +7466,14 @@ fi
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
-$as_echo_n "checking for sysroot... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+printf %s "checking for sysroot... " >&6; }
 
 # Check whether --with-sysroot was given.
-if test "${with_sysroot+set}" = set; then :
+if test ${with_sysroot+y}
+then :
   withval=$with_sysroot;
-else
+else $as_nop
   with_sysroot=no
 fi
 
@@ -6646,24 +7491,25 @@ case $with_sysroot in #(
  no|'')
    ;; #(
  *)
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
-$as_echo "$with_sysroot" >&6; }
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
+printf "%s\n" "$with_sysroot" >&6; }
    as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
    ;;
 esac
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
-$as_echo "${lt_sysroot:-no}" >&6; }
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+printf "%s\n" "${lt_sysroot:-no}" >&6; }
 
 
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
-$as_echo_n "checking for a working dd... " >&6; }
-if ${ac_cv_path_lt_DD+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
+printf %s "checking for a working dd... " >&6; }
+if test ${ac_cv_path_lt_DD+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   printf 0123456789abcdef0123456789abcdef >conftest.i
 cat conftest.i conftest.i >conftest2.i
 : ${lt_DD:=$DD}
@@ -6674,10 +7520,15 @@ if test -z "$lt_DD"; then
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in dd; do
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in dd
+   do
     for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
+      ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext"
       as_fn_executable_p "$ac_path_lt_DD" || continue
 if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
   cmp -s conftest.i conftest.out \
@@ -6697,15 +7548,16 @@ fi
 
 rm -f conftest.i conftest2.i conftest.out
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
-$as_echo "$ac_cv_path_lt_DD" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
+printf "%s\n" "$ac_cv_path_lt_DD" >&6; }
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
-$as_echo_n "checking how to truncate binary pipes... " >&6; }
-if ${lt_cv_truncate_bin+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
+printf %s "checking how to truncate binary pipes... " >&6; }
+if test ${lt_cv_truncate_bin+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   printf 0123456789abcdef0123456789abcdef >conftest.i
 cat conftest.i conftest.i >conftest2.i
 lt_cv_truncate_bin=
@@ -6716,8 +7568,8 @@ fi
 rm -f conftest.i conftest2.i conftest.out
 test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
-$as_echo "$lt_cv_truncate_bin" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
+printf "%s\n" "$lt_cv_truncate_bin" >&6; }
 
 
 
@@ -6740,7 +7592,8 @@ func_cc_basename ()
 }
 
 # Check whether --enable-libtool-lock was given.
-if test "${enable_libtool_lock+set}" = set; then :
+if test ${enable_libtool_lock+y}
+then :
   enableval=$enable_libtool_lock;
 fi
 
@@ -6756,7 +7609,7 @@ ia64-*-hpux*)
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
     case `/usr/bin/file conftest.$ac_objext` in
       *ELF-32*)
@@ -6776,7 +7629,7 @@ ia64-*-hpux*)
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
     if test yes = "$lt_cv_prog_gnu_ld"; then
       case `/usr/bin/file conftest.$ac_objext` in
@@ -6814,7 +7667,7 @@ mips64*-*linux*)
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
     emul=elf
     case `/usr/bin/file conftest.$ac_objext` in
@@ -6855,7 +7708,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
     case `/usr/bin/file conftest.o` in
       *32-bit*)
@@ -6918,11 +7771,12 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
   SAVE_CFLAGS=$CFLAGS
   CFLAGS="$CFLAGS -belf"
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
-$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
-if ${lt_cv_cc_needs_belf+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+printf %s "checking whether the C compiler needs -belf... " >&6; }
+if test ${lt_cv_cc_needs_belf+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -6933,19 +7787,20 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   lt_cv_cc_needs_belf=yes
-else
+else $as_nop
   lt_cv_cc_needs_belf=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
      ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -6954,8 +7809,8 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
-$as_echo "$lt_cv_cc_needs_belf" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+printf "%s\n" "$lt_cv_cc_needs_belf" >&6; }
   if test yes != "$lt_cv_cc_needs_belf"; then
     # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
     CFLAGS=$SAVE_CFLAGS
@@ -6968,7 +7823,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
     case `/usr/bin/file conftest.o` in
     *64-bit*)
@@ -7005,11 +7860,12 @@ need_locks=$enable_libtool_lock
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
 set dummy ${ac_tool_prefix}mt; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_MANIFEST_TOOL+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$MANIFEST_TOOL"; then
   ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
 else
@@ -7017,11 +7873,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7032,11 +7892,11 @@ fi
 fi
 MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
 if test -n "$MANIFEST_TOOL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
-$as_echo "$MANIFEST_TOOL" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+printf "%s\n" "$MANIFEST_TOOL" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -7045,11 +7905,12 @@ if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
   ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
   # Extract the first word of "mt", so it can be a program name with args.
 set dummy mt; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_MANIFEST_TOOL"; then
   ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
 else
@@ -7057,11 +7918,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7072,11 +7937,11 @@ fi
 fi
 ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
 if test -n "$ac_ct_MANIFEST_TOOL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
-$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_MANIFEST_TOOL" = x; then
@@ -7084,8 +7949,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
@@ -7095,11 +7960,12 @@ else
 fi
 
 test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
-$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
-if ${lt_cv_path_mainfest_tool+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if test ${lt_cv_path_mainfest_tool+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_path_mainfest_tool=no
   echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
   $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
@@ -7109,8 +7975,8 @@ else
   fi
   rm -f conftest*
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
-$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; }
 if test yes != "$lt_cv_path_mainfest_tool"; then
   MANIFEST_TOOL=:
 fi
@@ -7125,11 +7991,12 @@ fi
     if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
 set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_DSYMUTIL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_DSYMUTIL+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$DSYMUTIL"; then
   ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
 else
@@ -7137,11 +8004,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7152,11 +8023,11 @@ fi
 fi
 DSYMUTIL=$ac_cv_prog_DSYMUTIL
 if test -n "$DSYMUTIL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
-$as_echo "$DSYMUTIL" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+printf "%s\n" "$DSYMUTIL" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -7165,11 +8036,12 @@ if test -z "$ac_cv_prog_DSYMUTIL"; then
   ac_ct_DSYMUTIL=$DSYMUTIL
   # Extract the first word of "dsymutil", so it can be a program name with args.
 set dummy dsymutil; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_DSYMUTIL+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_DSYMUTIL"; then
   ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
 else
@@ -7177,11 +8049,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7192,11 +8068,11 @@ fi
 fi
 ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
 if test -n "$ac_ct_DSYMUTIL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
-$as_echo "$ac_ct_DSYMUTIL" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+printf "%s\n" "$ac_ct_DSYMUTIL" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_DSYMUTIL" = x; then
@@ -7204,8 +8080,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     DSYMUTIL=$ac_ct_DSYMUTIL
@@ -7217,11 +8093,12 @@ fi
     if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
 set dummy ${ac_tool_prefix}nmedit; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_NMEDIT+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_NMEDIT+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$NMEDIT"; then
   ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
 else
@@ -7229,11 +8106,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7244,11 +8125,11 @@ fi
 fi
 NMEDIT=$ac_cv_prog_NMEDIT
 if test -n "$NMEDIT"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
-$as_echo "$NMEDIT" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+printf "%s\n" "$NMEDIT" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -7257,11 +8138,12 @@ if test -z "$ac_cv_prog_NMEDIT"; then
   ac_ct_NMEDIT=$NMEDIT
   # Extract the first word of "nmedit", so it can be a program name with args.
 set dummy nmedit; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_NMEDIT+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_NMEDIT"; then
   ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
 else
@@ -7269,11 +8151,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_NMEDIT="nmedit"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7284,11 +8170,11 @@ fi
 fi
 ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
 if test -n "$ac_ct_NMEDIT"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
-$as_echo "$ac_ct_NMEDIT" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+printf "%s\n" "$ac_ct_NMEDIT" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_NMEDIT" = x; then
@@ -7296,8 +8182,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     NMEDIT=$ac_ct_NMEDIT
@@ -7309,11 +8195,12 @@ fi
     if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
 set dummy ${ac_tool_prefix}lipo; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_LIPO+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_LIPO+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$LIPO"; then
   ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
 else
@@ -7321,11 +8208,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7336,11 +8227,11 @@ fi
 fi
 LIPO=$ac_cv_prog_LIPO
 if test -n "$LIPO"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
-$as_echo "$LIPO" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+printf "%s\n" "$LIPO" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -7349,11 +8240,12 @@ if test -z "$ac_cv_prog_LIPO"; then
   ac_ct_LIPO=$LIPO
   # Extract the first word of "lipo", so it can be a program name with args.
 set dummy lipo; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_LIPO+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_LIPO"; then
   ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
 else
@@ -7361,11 +8253,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_LIPO="lipo"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7376,11 +8272,11 @@ fi
 fi
 ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
 if test -n "$ac_ct_LIPO"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
-$as_echo "$ac_ct_LIPO" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+printf "%s\n" "$ac_ct_LIPO" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_LIPO" = x; then
@@ -7388,8 +8284,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     LIPO=$ac_ct_LIPO
@@ -7401,11 +8297,12 @@ fi
     if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
 set dummy ${ac_tool_prefix}otool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_OTOOL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_OTOOL+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$OTOOL"; then
   ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
 else
@@ -7413,11 +8310,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7428,11 +8329,11 @@ fi
 fi
 OTOOL=$ac_cv_prog_OTOOL
 if test -n "$OTOOL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
-$as_echo "$OTOOL" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+printf "%s\n" "$OTOOL" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -7441,11 +8342,12 @@ if test -z "$ac_cv_prog_OTOOL"; then
   ac_ct_OTOOL=$OTOOL
   # Extract the first word of "otool", so it can be a program name with args.
 set dummy otool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_OTOOL+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_OTOOL"; then
   ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
 else
@@ -7453,11 +8355,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_OTOOL="otool"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7468,11 +8374,11 @@ fi
 fi
 ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
 if test -n "$ac_ct_OTOOL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
-$as_echo "$ac_ct_OTOOL" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+printf "%s\n" "$ac_ct_OTOOL" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_OTOOL" = x; then
@@ -7480,8 +8386,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     OTOOL=$ac_ct_OTOOL
@@ -7493,11 +8399,12 @@ fi
     if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
 set dummy ${ac_tool_prefix}otool64; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_OTOOL64+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_OTOOL64+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$OTOOL64"; then
   ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
 else
@@ -7505,11 +8412,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7520,11 +8431,11 @@ fi
 fi
 OTOOL64=$ac_cv_prog_OTOOL64
 if test -n "$OTOOL64"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
-$as_echo "$OTOOL64" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+printf "%s\n" "$OTOOL64" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -7533,11 +8444,12 @@ if test -z "$ac_cv_prog_OTOOL64"; then
   ac_ct_OTOOL64=$OTOOL64
   # Extract the first word of "otool64", so it can be a program name with args.
 set dummy otool64; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_OTOOL64+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_OTOOL64"; then
   ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
 else
@@ -7545,11 +8457,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_OTOOL64="otool64"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -7560,11 +8476,11 @@ fi
 fi
 ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
 if test -n "$ac_ct_OTOOL64"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
-$as_echo "$ac_ct_OTOOL64" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+printf "%s\n" "$ac_ct_OTOOL64" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_OTOOL64" = x; then
@@ -7572,8 +8488,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     OTOOL64=$ac_ct_OTOOL64
@@ -7608,11 +8524,12 @@ fi
 
 
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
-$as_echo_n "checking for -single_module linker flag... " >&6; }
-if ${lt_cv_apple_cc_single_mod+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+printf %s "checking for -single_module linker flag... " >&6; }
+if test ${lt_cv_apple_cc_single_mod+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_apple_cc_single_mod=no
       if test -z "$LT_MULTI_MODULE"; then
        # By default we will add the -single_module flag. You can override
@@ -7641,14 +8558,15 @@ else
        rm -f conftest.*
       fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
-$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; }
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
-$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
-if ${lt_cv_ld_exported_symbols_list+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+printf %s "checking for -exported_symbols_list linker flag... " >&6; }
+if test ${lt_cv_ld_exported_symbols_list+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_ld_exported_symbols_list=no
       save_LDFLAGS=$LDFLAGS
       echo "_main" > conftest.sym
@@ -7657,31 +8575,33 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   lt_cv_ld_exported_symbols_list=yes
-else
+else $as_nop
   lt_cv_ld_exported_symbols_list=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
        LDFLAGS=$save_LDFLAGS
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
-$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; }
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
-$as_echo_n "checking for -force_load linker flag... " >&6; }
-if ${lt_cv_ld_force_load+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+printf %s "checking for -force_load linker flag... " >&6; }
+if test ${lt_cv_ld_force_load+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_ld_force_load=no
       cat > conftest.c << _LT_EOF
 int forced_loaded() { return 2;}
@@ -7709,8 +8629,8 @@ _LT_EOF
         rm -rf conftest.dSYM
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
-$as_echo "$lt_cv_ld_force_load" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+printf "%s\n" "$lt_cv_ld_force_load" >&6; }
     case $host_os in
     rhapsody* | darwin1.[012])
       _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
@@ -7721,11 +8641,11 @@ $as_echo "$lt_cv_ld_force_load" >&6; }
       # to the OS version, if on x86, and 10.4, the deployment
       # target defaults to 10.4. Don't you love it?
       case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
-       10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+       10.0,*86*-darwin8*|10.0,*-darwin[912]*)
          _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
        10.[012][,.]*)
          _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
-       10.*)
+       10.*|11.*)
          _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
       esac
     ;;
@@ -7781,19 +8701,14 @@ func_munge_path_list ()
     esac
 }
 
-for ac_header in dlfcn.h
-do :
-  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
 "
-if test "x$ac_cv_header_dlfcn_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_DLFCN_H 1
-_ACEOF
+if test "x$ac_cv_header_dlfcn_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h
 
 fi
 
-done
-
 
 
 
@@ -7809,7 +8724,8 @@ done
 
 
             # Check whether --enable-shared was given.
-if test "${enable_shared+set}" = set; then :
+if test ${enable_shared+y}
+then :
   enableval=$enable_shared; p=${PACKAGE-default}
     case $enableval in
     yes) enable_shared=yes ;;
@@ -7827,7 +8743,7 @@ if test "${enable_shared+set}" = set; then :
       IFS=$lt_save_ifs
       ;;
     esac
-else
+else $as_nop
   enable_shared=yes
 fi
 
@@ -7840,7 +8756,8 @@ fi
 
 
   # Check whether --enable-static was given.
-if test "${enable_static+set}" = set; then :
+if test ${enable_static+y}
+then :
   enableval=$enable_static; p=${PACKAGE-default}
     case $enableval in
     yes) enable_static=yes ;;
@@ -7858,7 +8775,7 @@ if test "${enable_static+set}" = set; then :
       IFS=$lt_save_ifs
       ;;
     esac
-else
+else $as_nop
   enable_static=yes
 fi
 
@@ -7872,7 +8789,8 @@ fi
 
 
 # Check whether --with-pic was given.
-if test "${with_pic+set}" = set; then :
+if test ${with_pic+y}
+then :
   withval=$with_pic; lt_p=${PACKAGE-default}
     case $withval in
     yes|no) pic_mode=$withval ;;
@@ -7889,7 +8807,7 @@ if test "${with_pic+set}" = set; then :
       IFS=$lt_save_ifs
       ;;
     esac
-else
+else $as_nop
   pic_mode=default
 fi
 
@@ -7901,7 +8819,8 @@ fi
 
 
   # Check whether --enable-fast-install was given.
-if test "${enable_fast_install+set}" = set; then :
+if test ${enable_fast_install+y}
+then :
   enableval=$enable_fast_install; p=${PACKAGE-default}
     case $enableval in
     yes) enable_fast_install=yes ;;
@@ -7919,7 +8838,7 @@ if test "${enable_fast_install+set}" = set; then :
       IFS=$lt_save_ifs
       ;;
     esac
-else
+else $as_nop
   enable_fast_install=yes
 fi
 
@@ -7933,11 +8852,12 @@ fi
   shared_archive_member_spec=
 case $host,$enable_shared in
 power*-*-aix[5-9]*,yes)
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
-$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
+printf %s "checking which variant of shared library versioning to provide... " >&6; }
 
 # Check whether --with-aix-soname was given.
-if test "${with_aix_soname+set}" = set; then :
+if test ${with_aix_soname+y}
+then :
   withval=$with_aix_soname; case $withval in
     aix|svr4|both)
       ;;
@@ -7946,18 +8866,19 @@ if test "${with_aix_soname+set}" = set; then :
       ;;
     esac
     lt_cv_with_aix_soname=$with_aix_soname
-else
-  if ${lt_cv_with_aix_soname+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+else $as_nop
+  if test ${lt_cv_with_aix_soname+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_with_aix_soname=aix
 fi
 
     with_aix_soname=$lt_cv_with_aix_soname
 fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
-$as_echo "$with_aix_soname" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
+printf "%s\n" "$with_aix_soname" >&6; }
   if test aix != "$with_aix_soname"; then
     # For the AIX way of multilib, we name the shared archive member
     # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
@@ -8039,11 +8960,12 @@ if test -n "${ZSH_VERSION+set}"; then
    setopt NO_GLOB_SUBST
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
-$as_echo_n "checking for objdir... " >&6; }
-if ${lt_cv_objdir+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+printf %s "checking for objdir... " >&6; }
+if test ${lt_cv_objdir+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   rm -f .libs 2>/dev/null
 mkdir .libs 2>/dev/null
 if test -d .libs; then
@@ -8054,17 +8976,15 @@ else
 fi
 rmdir .libs 2>/dev/null
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
-$as_echo "$lt_cv_objdir" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+printf "%s\n" "$lt_cv_objdir" >&6; }
 objdir=$lt_cv_objdir
 
 
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define LT_OBJDIR "$lt_cv_objdir/"
-_ACEOF
+printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h
 
 
 
@@ -8110,11 +9030,12 @@ test -z "$MAGIC_CMD" && MAGIC_CMD=file
 case $deplibs_check_method in
 file_magic*)
   if test "$file_magic_cmd" = '$MAGIC_CMD'; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
-$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
-if ${lt_cv_path_MAGIC_CMD+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+printf %s "checking for ${ac_tool_prefix}file... " >&6; }
+if test ${lt_cv_path_MAGIC_CMD+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   case $MAGIC_CMD in
 [\\/*] |  ?:[\\/]*)
   lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
@@ -8163,11 +9084,11 @@ fi
 
 MAGIC_CMD=$lt_cv_path_MAGIC_CMD
 if test -n "$MAGIC_CMD"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
-$as_echo "$MAGIC_CMD" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+printf "%s\n" "$MAGIC_CMD" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -8176,11 +9097,12 @@ fi
 
 if test -z "$lt_cv_path_MAGIC_CMD"; then
   if test -n "$ac_tool_prefix"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
-$as_echo_n "checking for file... " >&6; }
-if ${lt_cv_path_MAGIC_CMD+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+printf %s "checking for file... " >&6; }
+if test ${lt_cv_path_MAGIC_CMD+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   case $MAGIC_CMD in
 [\\/*] |  ?:[\\/]*)
   lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
@@ -8229,11 +9151,11 @@ fi
 
 MAGIC_CMD=$lt_cv_path_MAGIC_CMD
 if test -n "$MAGIC_CMD"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
-$as_echo "$MAGIC_CMD" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+printf "%s\n" "$MAGIC_CMD" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -8318,11 +9240,12 @@ if test yes = "$GCC"; then
     lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
   esac
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
-$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
-if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if test ${lt_cv_prog_compiler_rtti_exceptions+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_rtti_exceptions=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
@@ -8353,8 +9276,8 @@ else
    $RM conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
-$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
 
 if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
     lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
@@ -8717,26 +9640,28 @@ case $host_os in
     ;;
 esac
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
-if ${lt_cv_prog_compiler_pic+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+printf %s "checking for $compiler option to produce PIC... " >&6; }
+if test ${lt_cv_prog_compiler_pic+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
-$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; }
 lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
 
 #
 # Check to make sure the PIC flag actually works.
 #
 if test -n "$lt_prog_compiler_pic"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
-$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
-if ${lt_cv_prog_compiler_pic_works+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if test ${lt_cv_prog_compiler_pic_works+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_pic_works=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
@@ -8767,8 +9692,8 @@ else
    $RM conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
-$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; }
 
 if test yes = "$lt_cv_prog_compiler_pic_works"; then
     case $lt_prog_compiler_pic in
@@ -8796,11 +9721,12 @@ fi
 # Check to make sure the static flag actually works.
 #
 wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
-if ${lt_cv_prog_compiler_static_works+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test ${lt_cv_prog_compiler_static_works+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_static_works=no
    save_LDFLAGS=$LDFLAGS
    LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
@@ -8824,8 +9750,8 @@ else
    LDFLAGS=$save_LDFLAGS
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
-$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; }
 
 if test yes = "$lt_cv_prog_compiler_static_works"; then
     :
@@ -8839,11 +9765,12 @@ fi
 
 
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if ${lt_cv_prog_compiler_c_o+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test ${lt_cv_prog_compiler_c_o+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_c_o=no
    $RM -r conftest 2>/dev/null
    mkdir conftest
@@ -8886,19 +9813,20 @@ else
    $RM conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
-$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; }
 
 
 
 
 
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if ${lt_cv_prog_compiler_c_o+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test ${lt_cv_prog_compiler_c_o+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_c_o=no
    $RM -r conftest 2>/dev/null
    mkdir conftest
@@ -8941,8 +9869,8 @@ else
    $RM conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
-$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; }
 
 
 
@@ -8950,19 +9878,19 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; }
 hard_links=nottested
 if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
   # do not overwrite the value of need_locks provided by the user
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
-$as_echo_n "checking if we can lock with hard links... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+printf %s "checking if we can lock with hard links... " >&6; }
   hard_links=yes
   $RM conftest*
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   touch conftest.a
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
-$as_echo "$hard_links" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+printf "%s\n" "$hard_links" >&6; }
   if test no = "$hard_links"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
     need_locks=warn
   fi
 else
@@ -8974,8 +9902,8 @@ fi
 
 
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
 
   runpath_var=
   allow_undefined_flag=
@@ -9533,21 +10461,23 @@ _LT_EOF
         if test set = "${lt_cv_aix_libpath+set}"; then
   aix_libpath=$lt_cv_aix_libpath
 else
-  if ${lt_cv_aix_libpath_+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  if test ${lt_cv_aix_libpath_+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
 
   lt_aix_libpath_sed='
       /Import File Strings/,/^$/ {
@@ -9562,7 +10492,7 @@ if ac_fn_c_try_link "$LINENO"; then :
     lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
   fi
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath_"; then
     lt_cv_aix_libpath_=/usr/lib:/lib
         if test set = "${lt_cv_aix_libpath+set}"; then
   aix_libpath=$lt_cv_aix_libpath
 else
-  if ${lt_cv_aix_libpath_+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  if test ${lt_cv_aix_libpath_+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
 
   lt_aix_libpath_sed='
       /Import File Strings/,/^$/ {
@@ -9615,7 +10547,7 @@ if ac_fn_c_try_link "$LINENO"; then :
     lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
   fi
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath_"; then
     lt_cv_aix_libpath_=/usr/lib:/lib
 
          # Older versions of the 11.00 compiler do not understand -b yet
          # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
-         { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
-$as_echo_n "checking if $CC understands -b... " >&6; }
-if ${lt_cv_prog_compiler__b+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+printf %s "checking if $CC understands -b... " >&6; }
+if test ${lt_cv_prog_compiler__b+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler__b=no
    save_LDFLAGS=$LDFLAGS
    LDFLAGS="$LDFLAGS -b"
@@ -9894,8 +10827,8 @@ else
    LDFLAGS=$save_LDFLAGS
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
-$as_echo "$lt_cv_prog_compiler__b" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+printf "%s\n" "$lt_cv_prog_compiler__b" >&6; }
 
 if test yes = "$lt_cv_prog_compiler__b"; then
     archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
        # work, assume that -exports_file does not work either and
        # implicitly export all symbols.
        # This should be the same for all languages, so no per-tag cache variable.
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
-$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
-if ${lt_cv_irix_exported_symbol+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if test ${lt_cv_irix_exported_symbol+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   save_LDFLAGS=$LDFLAGS
           LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 int foo (void) { return 0; }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   lt_cv_irix_exported_symbol=yes
-else
+else $as_nop
   lt_cv_irix_exported_symbol=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
            LDFLAGS=$save_LDFLAGS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
-$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; }
        if test yes = "$lt_cv_irix_exported_symbol"; then
           archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
        fi
@@ -10237,8 +11172,8 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
     fi
   fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
-$as_echo "$ld_shlibs" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+printf "%s\n" "$ld_shlibs" >&6; }
 test no = "$ld_shlibs" && can_build_shared=no
 
 with_gnu_ld=$with_gnu_ld
@@ -10274,18 +11209,19 @@ x|xyes)
       # Test whether the compiler implicitly links with -lc since on some
       # systems, -lgcc has to come before -lc. If gcc already passes -lc
       # to ld, don't add -lc before -lgcc.
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
-$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
-if ${lt_cv_archive_cmds_need_lc+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+printf %s "checking whether -lc should be explicitly linked in... " >&6; }
+if test ${lt_cv_archive_cmds_need_lc+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   $RM conftest*
        echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
        if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } 2>conftest.err; then
          soname=conftest
          lib=conftest
@@ -10303,7 +11239,7 @@ else
          if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
   (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
          then
            lt_cv_archive_cmds_need_lc=no
@@ -10317,8 +11253,8 @@ else
        $RM conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
-$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; }
       archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
       ;;
     esac
@@ -10477,8 +11413,8 @@ esac
 
 
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
-$as_echo_n "checking dynamic linker characteristics... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+printf %s "checking dynamic linker characteristics... " >&6; }
 
 if test yes = "$GCC"; then
   case $host_os in
@@ -11039,9 +11975,10 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   shlibpath_overrides_runpath=no
 
   # Some binutils ld are patched to set DT_RUNPATH
-  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  if test ${lt_cv_shlibpath_overrides_runpath+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_shlibpath_overrides_runpath=no
     save_LDFLAGS=$LDFLAGS
     save_libdir=$libdir
@@ -11051,19 +11988,21 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+if ac_fn_c_try_link "$LINENO"
+then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null
+then :
   lt_cv_shlibpath_overrides_runpath=yes
 fi
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
     LDFLAGS=$save_LDFLAGS
     libdir=$save_libdir
@@ -11307,8 +12246,8 @@ uts4*)
   dynamic_linker=no
   ;;
 esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
-$as_echo "$dynamic_linker" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+printf "%s\n" "$dynamic_linker" >&6; }
 test no = "$dynamic_linker" && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
@@ -11429,8 +12368,8 @@ configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
 
 
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
-$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+printf %s "checking how to hardcode library paths into programs... " >&6; }
 hardcode_action=
 if test -n "$hardcode_libdir_flag_spec" ||
    test -n "$runpath_var" ||
@@ -11454,8 +12393,8 @@ else
   # directories.
   hardcode_action=unsupported
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
-$as_echo "$hardcode_action" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+printf "%s\n" "$hardcode_action" >&6; }
 
 if test relink = "$hardcode_action" ||
    test yes = "$inherit_rpath"; then
@@ -11499,11 +12438,12 @@ else
 
   darwin*)
     # if libdl is installed we need to link against it
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
-$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if ${ac_cv_lib_dl_dlopen+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+printf %s "checking for dlopen in -ldl... " >&6; }
+if test ${ac_cv_lib_dl_dlopen+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldl  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11512,32 +12452,31 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char dlopen ();
 int
-main ()
+main (void)
 {
 return dlopen ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_dl_dlopen=yes
-else
+else $as_nop
   ac_cv_lib_dl_dlopen=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
-$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes
+then :
   lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
-else
+else $as_nop
 
     lt_cv_dlopen=dyld
     lt_cv_dlopen_libs=
 
   *)
     ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
-if test "x$ac_cv_func_shl_load" = xyes; then :
+if test "x$ac_cv_func_shl_load" = xyes
+then :
   lt_cv_dlopen=shl_load
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
-$as_echo_n "checking for shl_load in -ldld... " >&6; }
-if ${ac_cv_lib_dld_shl_load+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+printf %s "checking for shl_load in -ldld... " >&6; }
+if test ${ac_cv_lib_dld_shl_load+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldld  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11573,41 +12514,42 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char shl_load ();
 int
-main ()
+main (void)
 {
 return shl_load ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_dld_shl_load=yes
-else
+else $as_nop
   ac_cv_lib_dld_shl_load=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
-$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
-if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes
+then :
   lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
-else
+else $as_nop
   ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
-if test "x$ac_cv_func_dlopen" = xyes; then :
+if test "x$ac_cv_func_dlopen" = xyes
+then :
   lt_cv_dlopen=dlopen
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
-$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if ${ac_cv_lib_dl_dlopen+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+printf %s "checking for dlopen in -ldl... " >&6; }
+if test ${ac_cv_lib_dl_dlopen+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldl  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11616,37 +12558,37 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char dlopen ();
 int
-main ()
+main (void)
 {
 return dlopen ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_dl_dlopen=yes
-else
+else $as_nop
   ac_cv_lib_dl_dlopen=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
-$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes
+then :
   lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
-$as_echo_n "checking for dlopen in -lsvld... " >&6; }
-if ${ac_cv_lib_svld_dlopen+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+printf %s "checking for dlopen in -lsvld... " >&6; }
+if test ${ac_cv_lib_svld_dlopen+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lsvld  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11655,37 +12597,37 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char dlopen ();
 int
-main ()
+main (void)
 {
 return dlopen ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_svld_dlopen=yes
-else
+else $as_nop
   ac_cv_lib_svld_dlopen=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
-$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
-if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes
+then :
   lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
-$as_echo_n "checking for dld_link in -ldld... " >&6; }
-if ${ac_cv_lib_dld_dld_link+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+printf %s "checking for dld_link in -ldld... " >&6; }
+if test ${ac_cv_lib_dld_dld_link+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldld  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11694,30 +12636,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char dld_link ();
 int
-main ()
+main (void)
 {
 return dld_link ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_dld_dld_link=yes
-else
+else $as_nop
   ac_cv_lib_dld_dld_link=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
-$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
-if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes
+then :
   lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
 fi
 
     save_LIBS=$LIBS
     LIBS="$lt_cv_dlopen_libs $LIBS"
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
-$as_echo_n "checking whether a program can dlopen itself... " >&6; }
-if ${lt_cv_dlopen_self+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+printf %s "checking whether a program can dlopen itself... " >&6; }
+if test ${lt_cv_dlopen_self+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
          if test yes = "$cross_compiling"; then :
   lt_cv_dlopen_self=cross
 else
@@ -11839,7 +12781,7 @@ _LT_EOF
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
     (./conftest; exit; ) >&5 2>/dev/null
     lt_status=$?
@@ -11857,16 +12799,17 @@ rm -fr conftest*
 
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
-$as_echo "$lt_cv_dlopen_self" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+printf "%s\n" "$lt_cv_dlopen_self" >&6; }
 
     if test yes = "$lt_cv_dlopen_self"; then
       wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
-$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
-if ${lt_cv_dlopen_self_static+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+printf %s "checking whether a statically linked program can dlopen itself... " >&6; }
+if test ${lt_cv_dlopen_self_static+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
          if test yes = "$cross_compiling"; then :
   lt_cv_dlopen_self_static=cross
 else
@@ -11945,7 +12888,7 @@ _LT_EOF
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
   (eval $ac_link) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
     (./conftest; exit; ) >&5 2>/dev/null
     lt_status=$?
@@ -11963,8 +12906,8 @@ rm -fr conftest*
 
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
-$as_echo "$lt_cv_dlopen_self_static" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+printf "%s\n" "$lt_cv_dlopen_self_static" >&6; }
     fi
 
     CPPFLAGS=$save_CPPFLAGS
 
 striplib=
 old_striplib=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
-$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+printf %s "checking whether stripping libraries is possible... " >&6; }
 if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
   test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
   test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 else
 # FIXME - insert some real tests, host_os isn't really good enough
   case $host_os in
@@ -12016,16 +12959,16 @@ else
     if test -n "$STRIP"; then
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
     else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
     fi
     ;;
   *)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
     ;;
   esac
 fi
 
 
   # Report what library types will actually be built
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
-$as_echo_n "checking if libtool supports shared libraries... " >&6; }
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
-$as_echo "$can_build_shared" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+printf %s "checking if libtool supports shared libraries... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+printf "%s\n" "$can_build_shared" >&6; }
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
-$as_echo_n "checking whether to build shared libraries... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+printf %s "checking whether to build shared libraries... " >&6; }
   test no = "$can_build_shared" && enable_shared=no
 
   # On AIX, shared libraries and static libraries use the same namespace, and
@@ -12072,15 +13015,15 @@ $as_echo_n "checking whether to build shared libraries... " >&6; }
     fi
     ;;
   esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
-$as_echo "$enable_shared" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+printf "%s\n" "$enable_shared" >&6; }
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
-$as_echo_n "checking whether to build static libraries... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+printf %s "checking whether to build static libraries... " >&6; }
   # Make sure either enable_shared or enable_static is yes.
   test yes = "$enable_shared" || enable_static=yes
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
-$as_echo "$enable_static" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+printf "%s\n" "$enable_static" >&6; }
 
 
 
@@ -12119,21 +13062,22 @@ CC=$lt_save_CC
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
-$as_echo_n "checking target system type... " >&6; }
-if ${ac_cv_target+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+printf %s "checking target system type... " >&6; }
+if test ${ac_cv_target+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test "x$target_alias" = x; then
   ac_cv_target=$ac_cv_host
 else
-  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
-    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+  ac_cv_target=`$SHELL "${ac_aux_dir}config.sub" $target_alias` ||
+    as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $target_alias failed" "$LINENO" 5
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
-$as_echo "$ac_cv_target" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+printf "%s\n" "$ac_cv_target" >&6; }
 case $ac_cv_target in
 *-*-*) ;;
 *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
@@ -12161,7 +13105,8 @@ test -n "$target_alias" &&
 
 am__api_version='1.16'
 
-# Find a good install program.  We prefer a C program (faster),
+
+  # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
 # incompatible versions:
 # SysV /etc/install, /usr/sbin/install
@@ -12175,20 +13120,25 @@ am__api_version='1.16'
 # OS/2's system install, which has a completely different semantic
 # ./install, which can be erroneously created by make from ./install.sh.
 # Reject install programs that cannot install multiple files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
-$as_echo_n "checking for a BSD-compatible install... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+printf %s "checking for a BSD-compatible install... " >&6; }
 if test -z "$INSTALL"; then
-if ${ac_cv_path_install+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+if test ${ac_cv_path_install+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in #((
-  ./ | .// | /[cC]/* | \
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    # Account for fact that we put trailing slashes in our PATH walk.
+case $as_dir in #((
+  ./ | /[cC]/* | \
   /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
   ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
   /usr/ucb/* ) ;;
@@ -12198,13 +13148,13 @@ case $as_dir/ in #((
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-       if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+       if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then
          if test $ac_prog = install &&
-           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
            # AIX install.  It has an incompatible calling convention.
            :
          elif test $ac_prog = install &&
-           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
            # program-specific install script used by HP pwplus--don't use.
            :
          else
@@ -12212,12 +13162,12 @@ case $as_dir/ in #((
            echo one > conftest.one
            echo two > conftest.two
            mkdir conftest.dir
-           if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+           if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" &&
              test -s conftest.one && test -s conftest.two &&
              test -s conftest.dir/conftest.one &&
              test -s conftest.dir/conftest.two
            then
-             ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+             ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c"
              break 3
            fi
          fi
@@ -12233,7 +13183,7 @@ IFS=$as_save_IFS
 rm -rf conftest.one conftest.two conftest.dir
 
 fi
-  if test "${ac_cv_path_install+set}" = set; then
+  if test ${ac_cv_path_install+y}; then
     INSTALL=$ac_cv_path_install
   else
     # As a last resort, use the slow shell script.  Don't cache a
@@ -12243,8 +13193,8 @@ fi
     INSTALL=$ac_install_sh
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
-$as_echo "$INSTALL" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+printf "%s\n" "$INSTALL" >&6; }
 
 # Use test -z because SunOS4 sh mishandles braces in ${var-val}.
 # It thinks the first close brace ends the variable substitution.
@@ -12254,8 +13204,8 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
 
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
-$as_echo_n "checking whether build environment is sane... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+printf %s "checking whether build environment is sane... " >&6; }
 # Reject unsafe characters in $srcdir or the absolute working directory
 # name.  Accept space and tab only in the latter.
 am_lf='
@@ -12309,8 +13259,8 @@ else
    as_fn_error $? "newly created file is older than distributed files!
 Check your system clock" "$LINENO" 5
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 # If we didn't sleep, we still need to ensure time stamps of config.status and
 # generated files are strictly newer.
 am_sleep_pid=
@@ -12329,23 +13279,19 @@ test "$program_suffix" != NONE &&
 # Double any \ or $.
 # By default was `s,x,x', remove it if useless.
 ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
-program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"`
 
-if test x"${MISSING+set}" != xset; then
-  case $am_aux_dir in
-  *\ * | *\    *)
-    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
-  *)
-    MISSING="\${SHELL} $am_aux_dir/missing" ;;
-  esac
+
+  if test x"${MISSING+set}" != xset; then
+  MISSING="\${SHELL} '$am_aux_dir/missing'"
 fi
 # Use eval to expand $SHELL
 if eval "$MISSING --is-lightweight"; then
   am_missing_run="$MISSING "
 else
   am_missing_run=
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
-$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
 fi
 
 if test x"${install_sh+set}" != xset; then
@@ -12365,11 +13311,12 @@ if test "$cross_compiling" != no; then
   if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
 set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_STRIP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_STRIP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$STRIP"; then
   ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
 else
@@ -12377,11 +13324,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_STRIP="${ac_tool_prefix}strip"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 STRIP=$ac_cv_prog_STRIP
 if test -n "$STRIP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
-$as_echo "$STRIP" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+printf "%s\n" "$STRIP" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -12405,11 +13356,12 @@ if test -z "$ac_cv_prog_STRIP"; then
   ac_ct_STRIP=$STRIP
   # Extract the first word of "strip", so it can be a program name with args.
 set dummy strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_STRIP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_STRIP"; then
   ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
 else
@@ -12417,11 +13369,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_STRIP="strip"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
 if test -n "$ac_ct_STRIP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
-$as_echo "$ac_ct_STRIP" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+printf "%s\n" "$ac_ct_STRIP" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_STRIP" = x; then
@@ -12444,8 +13400,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     STRIP=$ac_ct_STRIP
 fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
-$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5
+printf %s "checking for a race-free mkdir -p... " >&6; }
 if test -z "$MKDIR_P"; then
-  if ${ac_cv_path_mkdir+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  if test ${ac_cv_path_mkdir+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_prog in mkdir gmkdir; do
         for ac_exec_ext in '' $ac_executable_extensions; do
-          as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
-          case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
-            'mkdir (GNU coreutils) '* | \
-            'mkdir (coreutils) '* | \
+          as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue
+          case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #(
+            'mkdir ('*'coreutils) '* | \
+            'BusyBox '* | \
             'mkdir (fileutils) '4.1*)
-              ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+              ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext
               break 3;;
           esac
         done
@@ -12486,7 +13448,7 @@ IFS=$as_save_IFS
 fi
 
   test -d ./--version && rmdir ./--version
-  if test "${ac_cv_path_mkdir+set}" = set; then
+  if test ${ac_cv_path_mkdir+y}; then
     MKDIR_P="$ac_cv_path_mkdir -p"
   else
     # As a last resort, use the slow shell script.  Don't cache a
     MKDIR_P="$ac_install_sh -d"
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
-$as_echo "$MKDIR_P" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+printf "%s\n" "$MKDIR_P" >&6; }
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
 set x ${MAKE-make}
-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval test \${ac_cv_prog_make_${ac_make}_set+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat >conftest.make <<\_ACEOF
 SHELL = /bin/sh
 all:
@@ -12521,12 +13484,12 @@ esac
 rm -f conftest.make
 fi
 if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
   SET_MAKE=
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
   SET_MAKE="MAKE=${MAKE-make}"
 fi
 
@@ -12543,8 +13506,8 @@ DEPDIR="${am__leading_dot}deps"
 
 ac_config_commands="$ac_config_commands depfiles"
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
-$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
+printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; }
 cat > confinc.mk << 'END'
 am__doit:
        @echo this is the am__doit target >confinc.out
@@ -12580,11 +13543,12 @@ esac
   fi
 done
 rm -f confinc.* confmf.*
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
-$as_echo "${_am_result}" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
+printf "%s\n" "${_am_result}" >&6; }
 
 # Check whether --enable-dependency-tracking was given.
-if test "${enable_dependency_tracking+set}" = set; then :
+if test ${enable_dependency_tracking+y}
+then :
   enableval=$enable_dependency_tracking;
 fi
 
@@ -12603,7 +13567,8 @@ fi
 
 
 # Check whether --enable-silent-rules was given.
-if test "${enable_silent_rules+set}" = set; then :
+if test ${enable_silent_rules+y}
+then :
   enableval=$enable_silent_rules;
 fi
 
@@ -12613,12 +13578,13 @@ case $enable_silent_rules in # (((
     *) AM_DEFAULT_VERBOSITY=1;;
 esac
 am_make=${MAKE-make}
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
-$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
-if ${am_cv_make_support_nested_variables+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if $as_echo 'TRUE=$(BAR$(V))
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+printf %s "checking whether $am_make supports nested variables... " >&6; }
+if test ${am_cv_make_support_nested_variables+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if printf "%s\n" 'TRUE=$(BAR$(V))
 BAR0=false
 BAR1=true
 V=1
@@ -12630,8 +13596,8 @@ else
   am_cv_make_support_nested_variables=no
 fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
-$as_echo "$am_cv_make_support_nested_variables" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+printf "%s\n" "$am_cv_make_support_nested_variables" >&6; }
 if test $am_cv_make_support_nested_variables = yes; then
     AM_V='$(V)'
   AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
 
 # Define the identity of the package.
  PACKAGE='nghttp2'
- VERSION='1.41.0'
+ VERSION='1.46.0'
 
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE "$PACKAGE"
-_ACEOF
+printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
 
 
-cat >>confdefs.h <<_ACEOF
-#define VERSION "$VERSION"
-_ACEOF
+printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h
 
 # Some tools Automake needs.
 
@@ -12715,11 +13677,12 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
 
 depcc="$CC"   am_compiler_list=
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
-$as_echo_n "checking dependency style of $depcc... " >&6; }
-if ${am_cv_CC_dependencies_compiler_type+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+printf %s "checking dependency style of $depcc... " >&6; }
+if test ${am_cv_CC_dependencies_compiler_type+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
   # We make a subdir and do the tests there.  Otherwise we can end up
   # making bogus files that we don't know about and never remove.  For
@@ -12826,8 +13789,8 @@ else
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
-$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; }
 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
 
  if
@@ -12841,6 +13804,20 @@ else
 fi
 
 
+# Variables for tags utilities; see am/tags.am
+if test -z "$CTAGS"; then
+  CTAGS=ctags
+fi
+
+if test -z "$ETAGS"; then
+  ETAGS=etags
+fi
+
+if test -z "$CSCOPE"; then
+  CSCOPE=cscope
+fi
+
+
 
 # POSIX will say in a future version that running "rm -f" with no argument
 # is OK; and we want to be able to make that assumption in our Makefile
@@ -12886,7 +13863,8 @@ fi
 
 
 # Check whether --enable-silent-rules was given.
-if test "${enable_silent_rules+set}" = set; then :
+if test ${enable_silent_rules+y}
+then :
   enableval=$enable_silent_rules;
 fi
 
@@ -12896,12 +13874,13 @@ case $enable_silent_rules in # (((
     *) AM_DEFAULT_VERBOSITY=0;;
 esac
 am_make=${MAKE-make}
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
-$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
-if ${am_cv_make_support_nested_variables+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if $as_echo 'TRUE=$(BAR$(V))
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+printf %s "checking whether $am_make supports nested variables... " >&6; }
+if test ${am_cv_make_support_nested_variables+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if printf "%s\n" 'TRUE=$(BAR$(V))
 BAR0=false
 BAR1=true
 V=1
@@ -12913,8 +13892,8 @@ else
   am_cv_make_support_nested_variables=no
 fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
-$as_echo "$am_cv_make_support_nested_variables" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+printf "%s\n" "$am_cv_make_support_nested_variables" >&6; }
 if test $am_cv_make_support_nested_variables = yes; then
     AM_V='$(V)'
   AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
 AM_BACKSLASH='\'
 
 
-LT_CURRENT=34
+LT_CURRENT=35
 
-LT_REVISION=0
+LT_REVISION=1
 
-LT_AGE=20
+LT_AGE=21
 
 
 major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/^0-9//g"`
@@ -12941,138 +13920,273 @@ PACKAGE_VERSION_NUM=`printf "0x%02x%02x%02x" "$major" "$minor" "$patch"`
 
 
 # Check whether --enable-werror was given.
-if test "${enable_werror+set}" = set; then :
+if test ${enable_werror+y}
+then :
   enableval=$enable_werror; werror=$enableval
-else
+else $as_nop
   werror=no
 fi
 
 
 # Check whether --enable-debug was given.
-if test "${enable_debug+set}" = set; then :
+if test ${enable_debug+y}
+then :
   enableval=$enable_debug; debug=$enableval
-else
+else $as_nop
   debug=no
 fi
 
 
 # Check whether --enable-threads was given.
-if test "${enable_threads+set}" = set; then :
+if test ${enable_threads+y}
+then :
   enableval=$enable_threads; threads=$enableval
-else
+else $as_nop
   threads=yes
 fi
 
 
 # Check whether --enable-app was given.
-if test "${enable_app+set}" = set; then :
+if test ${enable_app+y}
+then :
   enableval=$enable_app; request_app=$enableval
-else
+else $as_nop
   request_app=check
 fi
 
 
 # Check whether --enable-hpack-tools was given.
-if test "${enable_hpack_tools+set}" = set; then :
+if test ${enable_hpack_tools+y}
+then :
   enableval=$enable_hpack_tools; request_hpack_tools=$enableval
-else
+else $as_nop
   request_hpack_tools=check
 fi
 
 
 # Check whether --enable-asio-lib was given.
-if test "${enable_asio_lib+set}" = set; then :
+if test ${enable_asio_lib+y}
+then :
   enableval=$enable_asio_lib; request_asio_lib=$enableval
-else
+else $as_nop
   request_asio_lib=no
 fi
 
 
 # Check whether --enable-examples was given.
-if test "${enable_examples+set}" = set; then :
+if test ${enable_examples+y}
+then :
   enableval=$enable_examples; request_examples=$enableval
-else
+else $as_nop
   request_examples=check
 fi
 
 
 # Check whether --enable-python-bindings was given.
-if test "${enable_python_bindings+set}" = set; then :
+if test ${enable_python_bindings+y}
+then :
   enableval=$enable_python_bindings; request_python_bindings=$enableval
-else
+else $as_nop
   request_python_bindings=check
 fi
 
 
 # Check whether --enable-failmalloc was given.
-if test "${enable_failmalloc+set}" = set; then :
+if test ${enable_failmalloc+y}
+then :
   enableval=$enable_failmalloc; request_failmalloc=$enableval
-else
+else $as_nop
   request_failmalloc=yes
 fi
 
 
 # Check whether --enable-lib-only was given.
-if test "${enable_lib_only+set}" = set; then :
+if test ${enable_lib_only+y}
+then :
   enableval=$enable_lib_only; request_lib_only=$enableval
-else
+else $as_nop
   request_lib_only=no
 fi
 
 
+# Check whether --enable-http3 was given.
+if test ${enable_http3+y}
+then :
+  enableval=$enable_http3; request_http3=$enableval
+else $as_nop
+  request_http3=no
+fi
+
+
 
 # Check whether --with-libxml2 was given.
-if test "${with_libxml2+set}" = set; then :
+if test ${with_libxml2+y}
+then :
   withval=$with_libxml2; request_libxml2=$withval
-else
+else $as_nop
   request_libxml2=check
 fi
 
 
 
+# Check whether --with-jansson was given.
+if test ${with_jansson+y}
+then :
+  withval=$with_jansson; request_jansson=$withval
+else $as_nop
+  request_jansson=check
+fi
+
+
+
+# Check whether --with-zlib was given.
+if test ${with_zlib+y}
+then :
+  withval=$with_zlib; request_zlib=$withval
+else $as_nop
+  request_zlib=check
+fi
+
+
+
+# Check whether --with-libevent-openssl was given.
+if test ${with_libevent_openssl+y}
+then :
+  withval=$with_libevent_openssl; request_libevent_openssl=$withval
+else $as_nop
+  request_libevent_openssl=check
+fi
+
+
+
+# Check whether --with-libcares was given.
+if test ${with_libcares+y}
+then :
+  withval=$with_libcares; request_libcares=$withval
+else $as_nop
+  request_libcares=check
+fi
+
+
+
+# Check whether --with-openssl was given.
+if test ${with_openssl+y}
+then :
+  withval=$with_openssl; request_openssl=$withval
+else $as_nop
+  request_openssl=check
+fi
+
+
+
+# Check whether --with-libev was given.
+if test ${with_libev+y}
+then :
+  withval=$with_libev; request_libev=$withval
+else $as_nop
+  request_libev=check
+fi
+
+
+
+# Check whether --with-cunit was given.
+if test ${with_cunit+y}
+then :
+  withval=$with_cunit; request_cunit=$withval
+else $as_nop
+  request_cunit=check
+fi
+
+
+
 # Check whether --with-jemalloc was given.
-if test "${with_jemalloc+set}" = set; then :
+if test ${with_jemalloc+y}
+then :
   withval=$with_jemalloc; request_jemalloc=$withval
-else
+else $as_nop
   request_jemalloc=check
 fi
 
 
 
 # Check whether --with-systemd was given.
-if test "${with_systemd+set}" = set; then :
+if test ${with_systemd+y}
+then :
   withval=$with_systemd; request_systemd=$withval
-else
+else $as_nop
   request_systemd=check
 fi
 
 
 
 # Check whether --with-mruby was given.
-if test "${with_mruby+set}" = set; then :
+if test ${with_mruby+y}
+then :
   withval=$with_mruby; request_mruby=$withval
-else
+else $as_nop
   request_mruby=no
 fi
 
 
 
 # Check whether --with-neverbleed was given.
-if test "${with_neverbleed+set}" = set; then :
+if test ${with_neverbleed+y}
+then :
   withval=$with_neverbleed; request_neverbleed=$withval
-else
+else $as_nop
   request_neverbleed=no
 fi
 
 
 
 # Check whether --with-cython was given.
-if test "${with_cython+set}" = set; then :
+if test ${with_cython+y}
+then :
   withval=$with_cython; cython_path=$withval
 fi
 
 
 
+# Check whether --with-libngtcp2 was given.
+if test ${with_libngtcp2+y}
+then :
+  withval=$with_libngtcp2; request_libngtcp2=$withval
+else $as_nop
+  request_libngtcp2=check
+fi
+
+
+
+# Check whether --with-libnghttp3 was given.
+if test ${with_libnghttp3+y}
+then :
+  withval=$with_libnghttp3; request_libnghttp3=$withval
+else $as_nop
+  request_libnghttp3=check
+fi
+
+
+
+# Check whether --with-libbpf was given.
+if test ${with_libbpf+y}
+then :
+  withval=$with_libbpf; request_libbpf=$withval
+else $as_nop
+  request_libbpf=no
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -13082,11 +14196,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -13094,11 +14209,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -13122,11 +14241,12 @@ if test -z "$ac_cv_prog_CC"; then
   ac_ct_CC=$CC
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
@@ -13134,11 +14254,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_CC" = x; then
@@ -13161,8 +14285,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CC=$ac_ct_CC
@@ -13175,11 +14299,12 @@ if test -z "$CC"; then
           if test -n "$ac_tool_prefix"; then
     # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -13187,11 +14312,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
 if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -13228,15 +14358,19 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
      fi
     ac_cv_prog_CC="cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -13252,18 +14386,18 @@ if test $ac_prog_rejected = yes; then
     # However, it has the same basename, so the bogon will be chosen
     # first if we set CC to just the basename; use the full file name.
     shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+    ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
   fi
 fi
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -13274,11 +14408,12 @@ if test -z "$CC"; then
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -13286,11 +14421,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -13318,11 +14457,12 @@ if test -z "$CC"; then
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
@@ -13330,11 +14470,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -13361,8 +14505,8 @@ done
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CC=$ac_ct_CC
@@ -13370,25 +14514,129 @@ esac
 fi
 
 fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
+set dummy ${ac_tool_prefix}clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "clang", so it can be a program name with args.
+set dummy clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
 
 
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "no acceptable C compiler found in \$PATH
 See \`config.log' for more details" "$LINENO" 5; }
 
 # Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
 set X $ac_compile
 ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
+for ac_option in --version -v -V -qversion -version; do
   { { ac_try="$ac_compiler $ac_option >&5"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compiler $ac_option >&5") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -13398,20 +14646,21 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
   fi
   rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
 done
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
+printf %s "checking whether the compiler supports GNU C... " >&6; }
+if test ${ac_cv_c_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 #ifndef __GNUC__
        choke me
@@ -13421,29 +14670,33 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_compiler_gnu=yes
-else
+else $as_nop
   ac_compiler_gnu=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
 if test $ac_compiler_gnu = yes; then
   GCC=yes
 else
   GCC=
 fi
-ac_test_CFLAGS=${CFLAGS+set}
+ac_test_CFLAGS=${CFLAGS+y}
 ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+printf %s "checking whether $CC accepts -g... " >&6; }
+if test ${ac_cv_prog_cc_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_save_c_werror_flag=$ac_c_werror_flag
    ac_c_werror_flag=yes
    ac_cv_prog_cc_g=no
@@ -13452,57 +14705,60 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_prog_cc_g=yes
-else
+else $as_nop
   CFLAGS=""
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
 
-else
+else $as_nop
   ac_c_werror_flag=$ac_save_c_werror_flag
         CFLAGS="-g"
         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_prog_cc_g=yes
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    ac_c_werror_flag=$ac_save_c_werror_flag
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
+if test $ac_test_CFLAGS; then
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
   if test "$GCC" = yes; then
@@ -13517,94 +14773,144 @@ else
     CFLAGS=
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c89=no
+ac_prog_cc_stdc=no
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
+printf %s "checking for $CC option to enable C11 features... " >&6; }
+if test ${ac_cv_prog_cc_c11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c11=no
 ac_save_CC=$CC
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
+$ac_c_conftest_c11_program
 _ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+for ac_arg in '' -std=gnu11
 do
   CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c89=$ac_arg
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c11=$ac_arg
 fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c11" != "xno" && break
 done
 rm -f conftest.$ac_ext
 CC=$ac_save_CC
-
 fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
 
+if test "x$ac_cv_prog_cc_c11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
+     CC="$CC $ac_cv_prog_cc_c11"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
+  ac_prog_cc_stdc=c11
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
+printf %s "checking for $CC option to enable C99 features... " >&6; }
+if test ${ac_cv_prog_cc_c99+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c99_program
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c99" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c99" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
+     CC="$CC $ac_cv_prog_cc_c99"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+  ac_prog_cc_stdc=c99
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
+printf %s "checking for $CC option to enable C89 features... " >&6; }
+if test ${ac_cv_prog_cc_c89+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c89_program
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c89" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c89" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
+     CC="$CC $ac_cv_prog_cc_c89"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+  ac_prog_cc_stdc=c89
+fi
 fi
 
 ac_ext=c
@@ -13612,22 +14918,24 @@ ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
-$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
-if ${am_cv_prog_cc_c_o+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+
+
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+printf %s "checking whether $CC understands -c and -o together... " >&6; }
+if test ${am_cv_prog_cc_c_o+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
@@ -13655,8 +14963,8 @@ _ACEOF
   rm -f core conftest*
   unset am_i
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
-$as_echo "$am_cv_prog_cc_c_o" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+printf "%s\n" "$am_cv_prog_cc_c_o" >&6; }
 if test "$am_cv_prog_cc_c_o" != yes; then
    # Losing compiler, so override with the script.
    # FIXME: It is wrong to rewrite CC.
@@ -13672,6 +14980,12 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
+
+
+
+
+
+
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -13682,15 +14996,16 @@ if test -z "$CXX"; then
     CXX=$CCC
   else
     if test -n "$ac_tool_prefix"; then
-  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CXX"; then
   ac_cv_prog_CXX="$CXX" # Let the user override the test.
 else
@@ -13698,11 +15013,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 CXX=$ac_cv_prog_CXX
 if test -n "$CXX"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
-$as_echo "$CXX" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+printf "%s\n" "$CXX" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
 fi
 if test -z "$CXX"; then
   ac_ct_CXX=$CXX
-  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_CXX"; then
   ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
 else
@@ -13742,11 +15062,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CXX="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
 if test -n "$ac_ct_CXX"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
-$as_echo "$ac_ct_CXX" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+printf "%s\n" "$ac_ct_CXX" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -13773,8 +15097,8 @@ done
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CXX=$ac_ct_CXX
@@ -13784,7 +15108,7 @@ fi
   fi
 fi
 # Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
 set X $ac_compile
 ac_compiler=$2
 for ac_option in --version -v -V -qversion; do
@@ -13794,7 +15118,7 @@ case "(($ac_try" in
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compiler $ac_option >&5") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -13804,20 +15128,21 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
   fi
   rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
 done
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
-$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
-if ${ac_cv_cxx_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5
+printf %s "checking whether the compiler supports GNU C++... " >&6; }
+if test ${ac_cv_cxx_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 #ifndef __GNUC__
        choke me
@@ -13827,29 +15152,33 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ac_compiler_gnu=yes
-else
+else $as_nop
   ac_compiler_gnu=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
-$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
 if test $ac_compiler_gnu = yes; then
   GXX=yes
 else
   GXX=
 fi
-ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_test_CXXFLAGS=${CXXFLAGS+y}
 ac_save_CXXFLAGS=$CXXFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
-$as_echo_n "checking whether $CXX accepts -g... " >&6; }
-if ${ac_cv_prog_cxx_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+printf %s "checking whether $CXX accepts -g... " >&6; }
+if test ${ac_cv_prog_cxx_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_save_cxx_werror_flag=$ac_cxx_werror_flag
    ac_cxx_werror_flag=yes
    ac_cv_prog_cxx_g=no
@@ -13858,57 +15187,60 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ac_cv_prog_cxx_g=yes
-else
+else $as_nop
   CXXFLAGS=""
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
 
-else
+else $as_nop
   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
         CXXFLAGS="-g"
         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ac_cv_prog_cxx_g=yes
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    ac_cxx_werror_flag=$ac_save_cxx_werror_flag
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
-$as_echo "$ac_cv_prog_cxx_g" >&6; }
-if test "$ac_test_CXXFLAGS" = set; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+printf "%s\n" "$ac_cv_prog_cxx_g" >&6; }
+if test $ac_test_CXXFLAGS; then
   CXXFLAGS=$ac_save_CXXFLAGS
 elif test $ac_cv_prog_cxx_g = yes; then
   if test "$GXX" = yes; then
@@ -13923,6 +15255,100 @@ else
     CXXFLAGS=
   fi
 fi
+ac_prog_cxx_stdcxx=no
+if test x$ac_prog_cxx_stdcxx = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5
+printf %s "checking for $CXX option to enable C++11 features... " >&6; }
+if test ${ac_cv_prog_cxx_11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cxx_11=no
+ac_save_CXX=$CXX
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_cxx_conftest_cxx11_program
+_ACEOF
+for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA
+do
+  CXX="$ac_save_CXX $ac_arg"
+  if ac_fn_cxx_try_compile "$LINENO"
+then :
+  ac_cv_prog_cxx_cxx11=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cxx_cxx11" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CXX=$ac_save_CXX
+fi
+
+if test "x$ac_cv_prog_cxx_cxx11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cxx_cxx11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5
+printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; }
+     CXX="$CXX $ac_cv_prog_cxx_cxx11"
+fi
+  ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11
+  ac_prog_cxx_stdcxx=cxx11
+fi
+fi
+if test x$ac_prog_cxx_stdcxx = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5
+printf %s "checking for $CXX option to enable C++98 features... " >&6; }
+if test ${ac_cv_prog_cxx_98+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cxx_98=no
+ac_save_CXX=$CXX
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_cxx_conftest_cxx98_program
+_ACEOF
+for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA
+do
+  CXX="$ac_save_CXX $ac_arg"
+  if ac_fn_cxx_try_compile "$LINENO"
+then :
+  ac_cv_prog_cxx_cxx98=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cxx_cxx98" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CXX=$ac_save_CXX
+fi
+
+if test "x$ac_cv_prog_cxx_cxx98" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cxx_cxx98" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5
+printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; }
+     CXX="$CXX $ac_cv_prog_cxx_cxx98"
+fi
+  ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98
+  ac_prog_cxx_stdcxx=cxx98
+fi
+fi
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -13947,36 +15373,32 @@ ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
-$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+printf %s "checking how to run the C++ preprocessor... " >&6; }
 if test -z "$CXXCPP"; then
-  if ${ac_cv_prog_CXXCPP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-      # Double quotes because CXXCPP needs to be expanded
-    for CXXCPP in "$CXX -E" "/lib/cpp"
+  if test ${ac_cv_prog_CXXCPP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+      # Double quotes because $CXX needs to be expanded
+    for CXXCPP in "$CXX -E" cpp /lib/cpp
     do
       ac_preproc_ok=false
 for ac_cxx_preproc_warn_flag in '' yes
 do
   # Use a header file that comes with gcc, so configuring glibc
   # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+#include <limits.h>
                     Syntax error
 _ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
+if ac_fn_cxx_try_cpp "$LINENO"
+then :
 
-else
+else $as_nop
   # Broken: fails on valid input.
 continue
 fi
@@ -13988,10 +15410,11 @@ rm -f conftest.err conftest.i conftest.$ac_ext
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
+if ac_fn_cxx_try_cpp "$LINENO"
+then :
   # Broken: success on invalid input.
 continue
-else
+else $as_nop
   # Passes both tests.
 ac_preproc_ok=:
 break
@@ -14001,7 +15424,8 @@ rm -f conftest.err conftest.i conftest.$ac_ext
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
 rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
+if $ac_preproc_ok
+then :
   break
 fi
 
 else
   ac_cv_prog_CXXCPP=$CXXCPP
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
-$as_echo "$CXXCPP" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+printf "%s\n" "$CXXCPP" >&6; }
 ac_preproc_ok=false
 for ac_cxx_preproc_warn_flag in '' yes
 do
   # Use a header file that comes with gcc, so configuring glibc
   # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+#include <limits.h>
                     Syntax error
 _ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
+if ac_fn_cxx_try_cpp "$LINENO"
+then :
 
-else
+else $as_nop
   # Broken: fails on valid input.
 continue
 fi
@@ -14047,10 +15466,11 @@ rm -f conftest.err conftest.i conftest.$ac_ext
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
+if ac_fn_cxx_try_cpp "$LINENO"
+then :
   # Broken: success on invalid input.
 continue
-else
+else $as_nop
   # Passes both tests.
 ac_preproc_ok=:
 break
@@ -14060,11 +15480,12 @@ rm -f conftest.err conftest.i conftest.$ac_ext
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
 rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
+if $ac_preproc_ok
+then :
 
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
 See \`config.log' for more details" "$LINENO" 5; }
 fi
@@ -14200,17 +15621,18 @@ cc_basename=$func_cc_basename_result
 
 
 # Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
+if test ${with_gnu_ld+y}
+then :
   withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
-else
+else $as_nop
   with_gnu_ld=no
 fi
 
 ac_prog=ld
 if test yes = "$GCC"; then
   # Check if gcc -print-prog-name=ld gives a path.
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
-$as_echo_n "checking for ld used by $CC... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+printf %s "checking for ld used by $CC... " >&6; }
   case $host in
   *-*-mingw*)
     # gcc leaves a trailing carriage return, which upsets mingw
@@ -14239,15 +15661,16 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
     ;;
   esac
 elif test yes = "$with_gnu_ld"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
-$as_echo_n "checking for GNU ld... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+printf %s "checking for GNU ld... " >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
-$as_echo_n "checking for non-GNU ld... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+printf %s "checking for non-GNU ld... " >&6; }
 fi
-if ${lt_cv_path_LD+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+if test ${lt_cv_path_LD+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -z "$LD"; then
   lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
 
 LD=$lt_cv_path_LD
 if test -n "$LD"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
-$as_echo "$LD" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+printf "%s\n" "$LD" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
-$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if ${lt_cv_prog_gnu_ld+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+printf %s "checking if the linker ($LD) is GNU ld... " >&6; }
+if test ${lt_cv_prog_gnu_ld+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   # I'd rather use --version here, but apparently some GNU lds only accept -v.
 case `$LD -v 2>&1 </dev/null` in
 *GNU* | *'with BFD'*)
@@ -14298,8 +15722,8 @@ case `$LD -v 2>&1 </dev/null` in
   ;;
 esac
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
-$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; }
 with_gnu_ld=$lt_cv_prog_gnu_ld
 
 
@@ -14353,8 +15777,8 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
     fi
 
     # PORTME: fill in a description of your system's C++ link characteristics
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
     ld_shlibs_CXX=yes
     case $host_os in
       aix3*)
@@ -14492,21 +15916,23 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
           if test set = "${lt_cv_aix_libpath+set}"; then
   aix_libpath=$lt_cv_aix_libpath
 else
-  if ${lt_cv_aix_libpath__CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  if test ${lt_cv_aix_libpath__CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
+if ac_fn_cxx_try_link "$LINENO"
+then :
 
   lt_aix_libpath_sed='
       /Import File Strings/,/^$/ {
@@ -14521,7 +15947,7 @@ if ac_fn_cxx_try_link "$LINENO"; then :
     lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
   fi
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath__CXX"; then
     lt_cv_aix_libpath__CXX=/usr/lib:/lib
            if test set = "${lt_cv_aix_libpath+set}"; then
   aix_libpath=$lt_cv_aix_libpath
 else
-  if ${lt_cv_aix_libpath__CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  if test ${lt_cv_aix_libpath__CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
+if ac_fn_cxx_try_link "$LINENO"
+then :
 
   lt_aix_libpath_sed='
       /Import File Strings/,/^$/ {
@@ -14575,7 +16003,7 @@ if ac_fn_cxx_try_link "$LINENO"; then :
     lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
   fi
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath__CXX"; then
     lt_cv_aix_libpath__CXX=/usr/lib:/lib
@@ -15426,8 +16854,8 @@ fi
         ;;
     esac
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
-$as_echo "$ld_shlibs_CXX" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+printf "%s\n" "$ld_shlibs_CXX" >&6; }
     test no = "$ld_shlibs_CXX" && can_build_shared=no
 
     GCC_CXX=$GXX
@@ -15465,7 +16893,7 @@ esac
 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   # Parse the compiler output and extract the necessary
   # objects, libraries and library flags.
@@ -15946,26 +17374,28 @@ case $host_os in
     ;;
 esac
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
-if ${lt_cv_prog_compiler_pic_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+printf %s "checking for $compiler option to produce PIC... " >&6; }
+if test ${lt_cv_prog_compiler_pic_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
-$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; }
 lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
 
 #
 # Check to make sure the PIC flag actually works.
 #
 if test -n "$lt_prog_compiler_pic_CXX"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
-$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
-if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if test ${lt_cv_prog_compiler_pic_works_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_pic_works_CXX=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
@@ -15996,8 +17426,8 @@ else
    $RM conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
-$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
 
 if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then
     case $lt_prog_compiler_pic_CXX in
 # Check to make sure the static flag actually works.
 #
 wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
-if ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test ${lt_cv_prog_compiler_static_works_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_static_works_CXX=no
    save_LDFLAGS=$LDFLAGS
    LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
@@ -16047,8 +17478,8 @@ else
    LDFLAGS=$save_LDFLAGS
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
-$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; }
 
 if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then
     :
 
 
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test ${lt_cv_prog_compiler_c_o_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_c_o_CXX=no
    $RM -r conftest 2>/dev/null
    mkdir conftest
@@ -16106,16 +17538,17 @@ else
    $RM conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
-$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; }
 
 
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test ${lt_cv_prog_compiler_c_o_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_prog_compiler_c_o_CXX=no
    $RM -r conftest 2>/dev/null
    mkdir conftest
@@ -16158,8 +17591,8 @@ else
    $RM conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
-$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; }
 
 
 
@@ -16167,19 +17600,19 @@ $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
 hard_links=nottested
 if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then
   # do not overwrite the value of need_locks provided by the user
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
-$as_echo_n "checking if we can lock with hard links... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+printf %s "checking if we can lock with hard links... " >&6; }
   hard_links=yes
   $RM conftest*
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   touch conftest.a
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
-$as_echo "$hard_links" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+printf "%s\n" "$hard_links" >&6; }
   if test no = "$hard_links"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
     need_locks=warn
   fi
 else
@@ -16188,8 +17621,8 @@ fi
 
 
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
 
   export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
   exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
@@ -16231,8 +17664,8 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     ;;
   esac
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
-$as_echo "$ld_shlibs_CXX" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+printf "%s\n" "$ld_shlibs_CXX" >&6; }
 test no = "$ld_shlibs_CXX" && can_build_shared=no
 
 with_gnu_ld_CXX=$with_gnu_ld
@@ -16259,18 +17692,19 @@ x|xyes)
       # Test whether the compiler implicitly links with -lc since on some
       # systems, -lgcc has to come before -lc. If gcc already passes -lc
       # to ld, don't add -lc before -lgcc.
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
-$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
-if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+printf %s "checking whether -lc should be explicitly linked in... " >&6; }
+if test ${lt_cv_archive_cmds_need_lc_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   $RM conftest*
        echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
        if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } 2>conftest.err; then
          soname=conftest
          lib=conftest
@@ -16288,7 +17722,7 @@ else
          if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
   (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
          then
            lt_cv_archive_cmds_need_lc_CXX=no
@@ -16302,8 +17736,8 @@ else
        $RM conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
-$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
       archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
       ;;
     esac
@@ -16372,8 +17806,8 @@ esac
 
 
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
-$as_echo_n "checking dynamic linker characteristics... " >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+printf %s "checking dynamic linker characteristics... " >&6; }
 
 library_names_spec=
 libname_spec='lib$name'
@@ -16861,9 +18295,10 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   shlibpath_overrides_runpath=no
 
   # Some binutils ld are patched to set DT_RUNPATH
-  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  if test ${lt_cv_shlibpath_overrides_runpath+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   lt_cv_shlibpath_overrides_runpath=no
     save_LDFLAGS=$LDFLAGS
     save_libdir=$libdir
@@ -16873,19 +18308,21 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
-  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+if ac_fn_cxx_try_link "$LINENO"
+then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null
+then :
   lt_cv_shlibpath_overrides_runpath=yes
 fi
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
     LDFLAGS=$save_LDFLAGS
     libdir=$save_libdir
@@ -17129,8 +18566,8 @@ uts4*)
   dynamic_linker=no
   ;;
 esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
-$as_echo "$dynamic_linker" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+printf "%s\n" "$dynamic_linker" >&6; }
 test no = "$dynamic_linker" && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
@@ -17194,8 +18631,8 @@ configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
 
 
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
-$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+printf %s "checking how to hardcode library paths into programs... " >&6; }
 hardcode_action_CXX=
 if test -n "$hardcode_libdir_flag_spec_CXX" ||
    test -n "$runpath_var_CXX" ||
@@ -17219,8 +18656,8 @@ else
   # directories.
   hardcode_action_CXX=unsupported
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
-$as_echo "$hardcode_action_CXX" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+printf "%s\n" "$hardcode_action_CXX" >&6; }
 
 if test relink = "$hardcode_action_CXX" ||
    test yes = "$inherit_rpath_CXX"; then
@@ -17261,11 +18698,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 depcc="$CXX"  am_compiler_list=
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
-$as_echo_n "checking dependency style of $depcc... " >&6; }
-if ${am_cv_CXX_dependencies_compiler_type+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+printf %s "checking dependency style of $depcc... " >&6; }
+if test ${am_cv_CXX_dependencies_compiler_type+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
   # We make a subdir and do the tests there.  Otherwise we can end up
   # making bogus files that we don't know about and never remove.  For
@@ -17372,8 +18810,8 @@ else
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
-$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+printf "%s\n" "$am_cv_CXX_dependencies_compiler_type" >&6; }
 CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
 
  if
@@ -17392,40 +18830,36 @@ ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+printf %s "checking how to run the C preprocessor... " >&6; }
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+  if test ${ac_cv_prog_CPP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+      # Double quotes because $CC needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp
     do
       ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
 do
   # Use a header file that comes with gcc, so configuring glibc
   # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+#include <limits.h>
                     Syntax error
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+if ac_fn_c_try_cpp "$LINENO"
+then :
 
-else
+else $as_nop
   # Broken: fails on valid input.
 continue
 fi
@@ -17437,10 +18871,11 @@ rm -f conftest.err conftest.i conftest.$ac_ext
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+if ac_fn_c_try_cpp "$LINENO"
+then :
   # Broken: success on invalid input.
 continue
-else
+else $as_nop
   # Passes both tests.
 ac_preproc_ok=:
 break
@@ -17450,7 +18885,8 @@ rm -f conftest.err conftest.i conftest.$ac_ext
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
 rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
+if $ac_preproc_ok
+then :
   break
 fi
 
 else
   ac_cv_prog_CPP=$CPP
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+printf "%s\n" "$CPP" >&6; }
 ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
 do
   # Use a header file that comes with gcc, so configuring glibc
   # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+#include <limits.h>
                     Syntax error
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+if ac_fn_c_try_cpp "$LINENO"
+then :
 
-else
+else $as_nop
   # Broken: fails on valid input.
 continue
 fi
@@ -17496,10 +18927,11 @@ rm -f conftest.err conftest.i conftest.$ac_ext
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+if ac_fn_c_try_cpp "$LINENO"
+then :
   # Broken: success on invalid input.
 continue
-else
+else $as_nop
   # Passes both tests.
 ac_preproc_ok=:
 break
@@ -17509,11 +18941,12 @@ rm -f conftest.err conftest.i conftest.$ac_ext
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
 rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
+if $ac_preproc_ok
+then :
 
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
 See \`config.log' for more details" "$LINENO" 5; }
 fi
@@ -17525,24 +18958,25 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
-$as_echo_n "checking whether ln -s works... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+printf %s "checking whether ln -s works... " >&6; }
 LN_S=$as_ln_s
 if test "$LN_S" = "ln -s"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
-$as_echo "no, using $LN_S" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+printf "%s\n" "no, using $LN_S" >&6; }
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
 set x ${MAKE-make}
-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval test \${ac_cv_prog_make_${ac_make}_set+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat >conftest.make <<\_ACEOF
 SHELL = /bin/sh
 all:
@@ -17558,12 +18992,12 @@ esac
 rm -f conftest.make
 fi
 if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
   SET_MAKE=
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
   SET_MAKE="MAKE=${MAKE-make}"
 fi
 
@@ -17580,11 +19014,12 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
        if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
 set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PKG_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_PKG_CONFIG+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   case $PKG_CONFIG in
   [\\/]* | ?:[\\/]*)
   ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
@@ -17594,11 +19029,15 @@ else
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -17610,11 +19049,11 @@ esac
 fi
 PKG_CONFIG=$ac_cv_path_PKG_CONFIG
 if test -n "$PKG_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
-$as_echo "$PKG_CONFIG" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+printf "%s\n" "$PKG_CONFIG" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -17623,11 +19062,12 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then
   ac_pt_PKG_CONFIG=$PKG_CONFIG
   # Extract the first word of "pkg-config", so it can be a program name with args.
 set dummy pkg-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_ac_pt_PKG_CONFIG+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   case $ac_pt_PKG_CONFIG in
   [\\/]* | ?:[\\/]*)
   ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
@@ -17637,11 +19077,15 @@ else
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -17653,11 +19097,11 @@ esac
 fi
 ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
 if test -n "$ac_pt_PKG_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
-$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_pt_PKG_CONFIG" = x; then
@@ -17665,8 +19109,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     PKG_CONFIG=$ac_pt_PKG_CONFIG
 fi
 if test -n "$PKG_CONFIG"; then
        _pkg_min_version=0.20
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
-$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; }
        if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+               { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
        else
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+               { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
                PKG_CONFIG=""
        fi
 fi
 
         if test -n "$PYTHON"; then
       # If the user set $PYTHON, use it and don't search something else.
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 2.7" >&5
-$as_echo_n "checking whether $PYTHON version is >= 2.7... " >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 3.8" >&5
+printf %s "checking whether $PYTHON version is >= 3.8... " >&6; }
       prog="import sys
 # split strings by '.' and convert to numeric.  Append some zeros
 # because we need at least 4 digits for the hex conversion.
 # map returns an iterator in Python 3.0 and a list in 2.x
-minver = list(map(int, '2.7'.split('.'))) + [0, 0, 0]
+minver = list(map(int, '3.8'.split('.'))) + [0, 0, 0]
 minverhex = 0
 # xrange is not present in Python 3.0 and range returns an iterator
 for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i]
@@ -17713,23 +19157,25 @@ sys.exit(sys.hexversion < minverhex)"
    ($PYTHON -c "$prog") >&5 2>&5
    ac_status=$?
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+   (exit $ac_status); }
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
                               as_fn_error $? "Python interpreter is too old" "$LINENO" 5
 fi
       am_display_PYTHON=$PYTHON
     else
       # Otherwise, try each interpreter until we find one that satisfies
       # VERSION.
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 2.7" >&5
-$as_echo_n "checking for a Python interpreter with version >= 2.7... " >&6; }
-if ${am_cv_pathless_PYTHON+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 3.8" >&5
+printf %s "checking for a Python interpreter with version >= 3.8... " >&6; }
+if test ${am_cv_pathless_PYTHON+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
        for am_cv_pathless_PYTHON in python python2 python3  python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3  python3.2 python3.1 python3.0  python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1  python2.0 none; do
          test "$am_cv_pathless_PYTHON" = none && break
@@ -17737,7 +19183,7 @@ else
 # split strings by '.' and convert to numeric.  Append some zeros
 # because we need at least 4 digits for the hex conversion.
 # map returns an iterator in Python 3.0 and a list in 2.x
-minver = list(map(int, '2.7'.split('.'))) + [0, 0, 0]
+minver = list(map(int, '3.8'.split('.'))) + [0, 0, 0]
 minverhex = 0
 # xrange is not present in Python 3.0 and range returns an iterator
 for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i]
@@ -17746,24 +19192,26 @@ sys.exit(sys.hexversion < minverhex)"
    ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5
    ac_status=$?
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); }; then :
+   (exit $ac_status); }
+then :
   break
 fi
        done
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5
-$as_echo "$am_cv_pathless_PYTHON" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5
+printf "%s\n" "$am_cv_pathless_PYTHON" >&6; }
       # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON.
       if test "$am_cv_pathless_PYTHON" = none; then
        PYTHON=:
       else
         # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args.
 set dummy $am_cv_pathless_PYTHON; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PYTHON+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_PYTHON+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   case $PYTHON in
   [\\/]* | ?:[\\/]*)
   ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path.
@@ -17773,11 +19221,15 @@ else
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_PYTHON="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -17789,11 +19241,11 @@ esac
 fi
 PYTHON=$ac_cv_path_PYTHON
 if test -n "$PYTHON"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
-$as_echo "$PYTHON" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+printf "%s\n" "$PYTHON" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
   else
 
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5
-$as_echo_n "checking for $am_display_PYTHON version... " >&6; }
-if ${am_cv_python_version+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"`
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5
+printf %s "checking for $am_display_PYTHON version... " >&6; }
+if test ${am_cv_python_version+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[:2])"`
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5
-$as_echo "$am_cv_python_version" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5
+printf "%s\n" "$am_cv_python_version" >&6; }
   PYTHON_VERSION=$am_cv_python_version
 
 
 
-  PYTHON_PREFIX='${prefix}'
+  if test "x$prefix" = xNONE
+  then
+   am__usable_prefix=$ac_default_prefix
+  else
+   am__usable_prefix=$prefix
+  fi
 
-  PYTHON_EXEC_PREFIX='${exec_prefix}'
 
+# Check whether --with-python_prefix was given.
+if test ${with_python_prefix+y}
+then :
+  withval=$with_python_prefix;  am_python_prefix_subst="$withval"
+   am_cv_python_prefix="$withval"
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON prefix" >&5
+printf %s "checking for $am_display_PYTHON prefix... " >&6; }
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_prefix" >&5
+printf "%s\n" "$am_cv_python_prefix" >&6; }
+else $as_nop
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON prefix" >&5
+printf %s "checking for $am_display_PYTHON prefix... " >&6; }
+if test ${am_cv_python_prefix+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"`
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_prefix" >&5
+printf "%s\n" "$am_cv_python_prefix" >&6; }
+
+      case $am_cv_python_prefix in
+     $am__usable_prefix*)
+       am__strip_prefix=`echo "$am__usable_prefix" | sed 's|.|.|g'`
+       am_python_prefix_subst=`echo "$am_cv_python_prefix" | sed "s,^$am__strip_prefix,\\${prefix},"`
+       ;;
+     *)
+       am_python_prefix_subst=$am_cv_python_prefix
+       ;;
+  esac
 
+fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5
-$as_echo_n "checking for $am_display_PYTHON platform... " >&6; }
-if ${am_cv_python_platform+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  PYTHON_PREFIX=$am_python_prefix_subst
+
+
+
+# Check whether --with-python_exec_prefix was given.
+if test ${with_python_exec_prefix+y}
+then :
+  withval=$with_python_exec_prefix;  am_python_exec_prefix_subst="$withval"
+   am_cv_python_exec_prefix="$withval"
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON exec_prefix" >&5
+printf %s "checking for $am_display_PYTHON exec_prefix... " >&6; }
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5
+printf "%s\n" "$am_cv_python_exec_prefix" >&6; }
+else $as_nop
+
+    if test -n "$with_python_prefix"
+then :
+  am_python_exec_prefix_subst="$with_python_prefix"
+  am_cv_python_exec_prefix="$with_python_prefix"
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON exec_prefix" >&5
+printf %s "checking for $am_display_PYTHON exec_prefix... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5
+printf "%s\n" "$am_cv_python_exec_prefix" >&6; }
+else $as_nop
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON exec_prefix" >&5
+printf %s "checking for $am_display_PYTHON exec_prefix... " >&6; }
+if test ${am_cv_python_exec_prefix+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"`
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5
+printf "%s\n" "$am_cv_python_exec_prefix" >&6; }
+        if test "x$exec_prefix" = xNONE
+  then
+   am__usable_exec_prefix=$am__usable_prefix
+  else
+   am__usable_exec_prefix=$exec_prefix
+  fi
+  case $am_cv_python_exec_prefix in
+     $am__usable_exec_prefix*)
+       am__strip_prefix=`echo "$am__usable_exec_prefix" | sed 's|.|.|g'`
+       am_python_exec_prefix_subst=`echo "$am_cv_python_exec_prefix" | sed "s,^$am__strip_prefix,\\${exec_prefix},"`
+       ;;
+     *)
+       am_python_exec_prefix_subst=$am_cv_python_exec_prefix
+       ;;
+  esac
+
+fi
+fi
+
+  PYTHON_EXEC_PREFIX=$am_python_exec_prefix_subst
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5
+printf %s "checking for $am_display_PYTHON platform... " >&6; }
+if test ${am_cv_python_platform+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5
-$as_echo "$am_cv_python_platform" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5
+printf "%s\n" "$am_cv_python_platform" >&6; }
   PYTHON_PLATFORM=$am_cv_python_platform
 
 
@@ -17859,16 +19407,17 @@ except ImportError:
     pass"
 
 
-            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5
-$as_echo_n "checking for $am_display_PYTHON script directory... " >&6; }
-if ${am_cv_python_pythondir+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "x$prefix" = xNONE
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5
+printf %s "checking for $am_display_PYTHON script directory... " >&6; }
+if test ${am_cv_python_pythondir+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "x$am_cv_python_prefix" = x
      then
-       am_py_prefix=$ac_default_prefix
+       am_py_prefix=$am__usable_prefix
      else
-       am_py_prefix=$prefix
+       am_py_prefix=$am_cv_python_prefix
      fi
      am_cv_python_pythondir=`$PYTHON -c "
 $am_python_setup_sysconfig
@@ -17881,21 +19430,21 @@ sys.stdout.write(sitedir)"`
      case $am_cv_python_pythondir in
      $am_py_prefix*)
        am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
-       am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
+       am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,\\${PYTHON_PREFIX},"`
        ;;
      *)
        case $am_py_prefix in
          /usr|/System*) ;;
          *)
-         am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
+         am_cv_python_pythondir="\${PYTHON_PREFIX}/lib/python$PYTHON_VERSION/site-packages"
          ;;
        esac
        ;;
      esac
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5
-$as_echo "$am_cv_python_pythondir" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5
+printf "%s\n" "$am_cv_python_pythondir" >&6; }
   pythondir=$am_cv_python_pythondir
 
 
@@ -17903,43 +19452,44 @@ $as_echo "$am_cv_python_pythondir" >&6; }
   pkgpythondir=\${pythondir}/$PACKAGE
 
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5
-$as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; }
-if ${am_cv_python_pyexecdir+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "x$exec_prefix" = xNONE
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5
+printf %s "checking for $am_display_PYTHON extension module directory... " >&6; }
+if test ${am_cv_python_pyexecdir+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "x$am_cv_python_exec_prefix" = x
      then
-       am_py_exec_prefix=$am_py_prefix
+       am_py_exec_prefix=$am__usable_exec_prefix
      else
-       am_py_exec_prefix=$exec_prefix
+       am_py_exec_prefix=$am_cv_python_exec_prefix
      fi
      am_cv_python_pyexecdir=`$PYTHON -c "
 $am_python_setup_sysconfig
 if can_use_sysconfig:
-    sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
+    sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'})
 else:
     from distutils import sysconfig
-    sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
+    sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix')
 sys.stdout.write(sitedir)"`
      case $am_cv_python_pyexecdir in
      $am_py_exec_prefix*)
        am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
-       am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
+       am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,\\${PYTHON_EXEC_PREFIX},"`
        ;;
      *)
        case $am_py_exec_prefix in
          /usr|/System*) ;;
          *)
-          am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
+          am_cv_python_pyexecdir="\${PYTHON_EXEC_PREFIX}/lib/python$PYTHON_VERSION/site-packages"
           ;;
        esac
        ;;
      esac
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5
-$as_echo "$am_cv_python_pyexecdir" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5
+printf "%s\n" "$am_cv_python_pyexecdir" >&6; }
   pyexecdir=$am_cv_python_pyexecdir
 
 
@@ -17952,6 +19502,11 @@ $as_echo "$am_cv_python_pyexecdir" >&6; }
 
 
 
+if test "x$request_python_bindings" = "xyes" &&
+   test "x$PYTHON" = "x:"; then
+  as_fn_error $? "python was requested (enable-python-bindings) but not found" "$LINENO" 5
+fi
+
 if test "x$request_lib_only" = "xyes"; then
   request_app=no
   request_hpack_tools=no
@@ -17959,7 +19514,9 @@ if test "x$request_lib_only" = "xyes"; then
   request_python_bindings=no
 fi
 
-if test "x$request_python_bindings" != "xno"; then
+if test "x$request_python_bindings" != "xno" &&
+   test "x$PYTHON" != "x:"; then
+  # version check is broken
 
        #
        # Allow the use of a (user set) custom python version
@@ -17968,11 +19525,12 @@ if test "x$request_python_bindings" != "xno"; then
 
        # Extract the first word of "python[$PYTHON_VERSION]", so it can be a program name with args.
 set dummy python$PYTHON_VERSION; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PYTHON+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_PYTHON+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   case $PYTHON in
   [\\/]* | ?:[\\/]*)
   ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path.
@@ -17982,11 +19540,15 @@ else
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_PYTHON="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 PYTHON=$ac_cv_path_PYTHON
 if test -n "$PYTHON"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
-$as_echo "$PYTHON" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+printf "%s\n" "$PYTHON" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
        if test -z "$PYTHON"; then
-          { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find python$PYTHON_VERSION in your system path" >&5
-$as_echo "$as_me: WARNING: Cannot find python$PYTHON_VERSION in your system path" >&2;}
+          as_fn_error $? "Cannot find python$PYTHON_VERSION in your system path" "$LINENO" 5
           PYTHON_VERSION=""
-           no_python_devel=yes
        fi
 
-if test -z "$no_python_devel"; then :
-
        #
        # Check for a version of Python >= 2.1.0
        #
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a version of Python >= '2.1.0'" >&5
-$as_echo_n "checking for a version of Python >= '2.1.0'... " >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a version of Python >= '2.1.0'" >&5
+printf %s "checking for a version of Python >= '2.1.0'... " >&6; }
        ac_supports_python_ver=`$PYTHON -c "import sys; \
                ver = sys.version.split ()[0]; \
                print (ver >= '2.1.0')"`
        if test "$ac_supports_python_ver" != "True"; then
                if test -z "$PYTHON_NOVERSIONCHECK"; then
-                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-                       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
-This version of the AC_PYTHON_DEVEL macro
-doesn't work properly with versions of Python before
-2.1.0. You may need to re-run configure, setting the
-variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
-PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
-Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
-to something else than an empty string.
-" >&5
-$as_echo "$as_me: WARNING:
+                       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+                       { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
 This version of the AC_PYTHON_DEVEL macro
 doesn't work properly with versions of Python before
 2.1.0. You may need to re-run configure, setting the
-variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
+variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG,
 PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
 Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
 to something else than an empty string.
-" >&2;}
-                        no_python_devel=yes
+
+See \`config.log' for more details" "$LINENO" 5; }
                else
-                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: skip at user request" >&5
-$as_echo "skip at user request" >&6; }
+                       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: skip at user request" >&5
+printf "%s\n" "skip at user request" >&6; }
                fi
        else
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+               { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
        fi
 
-fi # AS_IF
-
-if test -z "$no_python_devel"; then :
-
        #
        # if the macro parameter ``version'' is set, honour it
        #
-       if test -n ">= '2.7'"; then
-               { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a version of Python >= '2.7'" >&5
-$as_echo_n "checking for a version of Python >= '2.7'... " >&6; }
+       if test -n ""; then
+               { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a version of Python " >&5
+printf %s "checking for a version of Python ... " >&6; }
                ac_supports_python_ver=`$PYTHON -c "import sys; \
                        ver = sys.version.split ()[0]; \
-                       print (ver >= '2.7')"`
+                       print (ver )"`
                if test "$ac_supports_python_ver" = "True"; then
-                  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+                  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
                else
-                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-                       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: this package requires Python >= '2.7'.
-If you have it installed, but it isn't the default Python
-interpreter in your system path, please pass the PYTHON_VERSION
-variable to configure. See \`\`configure --help'' for reference.
-" >&5
-$as_echo "$as_me: WARNING: this package requires Python >= '2.7'.
+                       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+                       as_fn_error $? "this package requires Python .
 If you have it installed, but it isn't the default Python
 interpreter in your system path, please pass the PYTHON_VERSION
 variable to configure. See \`\`configure --help'' for reference.
-" >&2;}
+" "$LINENO" 5
                        PYTHON_VERSION=""
-                        no_python_devel=yes
                fi
        fi
 
-fi # AS_IF
-
-if test -z "$no_python_devel"; then :
-
        #
        # Check if you have distutils, else fail
        #
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the distutils Python package" >&5
-$as_echo_n "checking for the distutils Python package... " >&6; }
-       ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
-       if test -z "$ac_distutils_result"; then
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the sysconfig Python package" >&5
+printf %s "checking for the sysconfig Python package... " >&6; }
+       ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1`
+       if test $? -eq 0; then
+               { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+               IMPORT_SYSCONFIG="import sysconfig"
        else
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-               { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot import Python module \"distutils\".
-Please check your Python installation. The error was:
-$ac_distutils_result" >&5
-$as_echo "$as_me: WARNING: cannot import Python module \"distutils\".
+               { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+
+               { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the distutils Python package" >&5
+printf %s "checking for the distutils Python package... " >&6; }
+               ac_sysconfig_result=`$PYTHON -c "from distutils import sysconfig" 2>&1`
+               if test $? -eq 0; then
+                       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+                       IMPORT_SYSCONFIG="from distutils import sysconfig"
+               else
+                       as_fn_error $? "cannot import Python module \"distutils\".
 Please check your Python installation. The error was:
-$ac_distutils_result" >&2;}
-               PYTHON_VERSION=""
-                no_python_devel=yes
+$ac_sysconfig_result" "$LINENO" 5
+                       PYTHON_VERSION=""
+               fi
        fi
 
-fi # AS_IF
-
-if test -z "$no_python_devel"; then :
-
        #
        # Check for Python include path
        #
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python include path" >&5
-$as_echo_n "checking for Python include path... " >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python include path" >&5
+printf %s "checking for Python include path... " >&6; }
        if test -z "$PYTHON_CPPFLAGS"; then
-               python_path=`$PYTHON -c "import distutils.sysconfig; \
-                       print (distutils.sysconfig.get_python_inc ());"`
-               plat_python_path=`$PYTHON -c "import distutils.sysconfig; \
-                       print (distutils.sysconfig.get_python_inc (plat_specific=1));"`
+               if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
+                       # sysconfig module has different functions
+                       python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_path ('include'));"`
+                       plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_path ('platinclude'));"`
+               else
+                       # old distutils way
+                       python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_python_inc ());"`
+                       plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_python_inc (plat_specific=1));"`
+               fi
                if test -n "${python_path}"; then
                        if test "${plat_python_path}" != "${python_path}"; then
                                python_path="-I$python_path -I$plat_python_path"
@@ -18138,23 +19687,23 @@ $as_echo_n "checking for Python include path... " >&6; }
                fi
                PYTHON_CPPFLAGS=$python_path
        fi
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CPPFLAGS" >&5
-$as_echo "$PYTHON_CPPFLAGS" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CPPFLAGS" >&5
+printf "%s\n" "$PYTHON_CPPFLAGS" >&6; }
 
 
        #
        # Check for Python library path
        #
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python library path" >&5
-$as_echo_n "checking for Python library path... " >&6; }
-       if test -z "$PYTHON_LDFLAGS"; then
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python library path" >&5
+printf %s "checking for Python library path... " >&6; }
+       if test -z "$PYTHON_LIBS"; then
                # (makes two attempts to ensure we've got a version number
                # from the interpreter)
                ac_python_version=`cat<<EOD | $PYTHON -
 
 # join all versioning strings, on some systems
 # major/minor numbers could be in different list elements
-from distutils.sysconfig import *
+from sysconfig import *
 e = get_config_var('VERSION')
 if e is not None:
        print(e)
@@ -18171,17 +19720,15 @@ EOD`
 
                # Make the versioning information available to the compiler
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_PYTHON "$ac_python_version"
-_ACEOF
+printf "%s\n" "#define HAVE_PYTHON \"$ac_python_version\"" >>confdefs.h
 
 
                # First, the library directory:
                ac_python_libdir=`cat<<EOD | $PYTHON -
 
 # There should be only one
-import distutils.sysconfig
-e = distutils.sysconfig.get_config_var('LIBDIR')
+$IMPORT_SYSCONFIG
+e = sysconfig.get_config_var('LIBDIR')
 if e is not None:
        print (e)
 EOD`
@@ -18189,8 +19736,8 @@ EOD`
                # Now, for the library:
                ac_python_library=`cat<<EOD | $PYTHON -
 
-import distutils.sysconfig
-c = distutils.sysconfig.get_config_vars()
+$IMPORT_SYSCONFIG
+c = sysconfig.get_config_vars()
 if 'LDVERSION' in c:
        print ('python'+c['LDVERSION'])
 else:
@@ -18205,86 +19752,104 @@ EOD`
                then
                        # use the official shared library
                        ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
-                       PYTHON_LDFLAGS="-L$ac_python_libdir -l$ac_python_library"
+                       PYTHON_LIBS="-L$ac_python_libdir -l$ac_python_library"
                else
                        # old way: use libpython from python_configdir
                        ac_python_libdir=`$PYTHON -c \
-                         "from distutils.sysconfig import get_python_lib as f; \
+                         "from sysconfig import get_python_lib as f; \
                          import os; \
                          print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
-                       PYTHON_LDFLAGS="-L$ac_python_libdir -lpython$ac_python_version"
+                       PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version"
                fi
 
-               if test -z "PYTHON_LDFLAGS"; then
-                       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
-  Cannot determine location of your Python DSO. Please check it was installed with
-  dynamic libraries enabled, or try setting PYTHON_LDFLAGS by hand.
-                       " >&5
-$as_echo "$as_me: WARNING:
+               if test -z "PYTHON_LIBS"; then
+                       as_fn_error $? "
   Cannot determine location of your Python DSO. Please check it was installed with
-  dynamic libraries enabled, or try setting PYTHON_LDFLAGS by hand.
-                       " >&2;}
-                        no_python_devel=yes
+  dynamic libraries enabled, or try setting PYTHON_LIBS by hand.
+                       " "$LINENO" 5
                fi
        fi
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LDFLAGS" >&5
-$as_echo "$PYTHON_LDFLAGS" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LIBS" >&5
+printf "%s\n" "$PYTHON_LIBS" >&6; }
 
 
-fi # AS_IF
+       #
+       # Check for site packages
+       #
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python site-packages path" >&5
+printf %s "checking for Python site-packages path... " >&6; }
+       if test -z "$PYTHON_SITE_PKG"; then
+               if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
+                       PYTHON_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_path('purelib'));"`
+               else
+                       # distutils.sysconfig way
+                       PYTHON_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_python_lib(0,0));"`
+               fi
+       fi
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_SITE_PKG" >&5
+printf "%s\n" "$PYTHON_SITE_PKG" >&6; }
 
-if test -z "$no_python_devel"; then :
 
        #
-       # Check for site packages
+       # Check for platform-specific site packages
        #
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python site-packages path" >&5
-$as_echo_n "checking for Python site-packages path... " >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python platform specific site-packages path" >&5
+printf %s "checking for Python platform specific site-packages path... " >&6; }
        if test -z "$PYTHON_SITE_PKG"; then
-               PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
-                       print (distutils.sysconfig.get_python_lib(0,0));"`
+               if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
+                       PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_path('platlib'));"`
+               else
+                       # distutils.sysconfig way
+                       PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_python_lib(1,0));"`
+               fi
        fi
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_SITE_PKG" >&5
-$as_echo "$PYTHON_SITE_PKG" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_PLATFORM_SITE_PKG" >&5
+printf "%s\n" "$PYTHON_PLATFORM_SITE_PKG" >&6; }
 
 
        #
        # libraries which must be linked in when embedding
        #
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking python extra libraries" >&5
-$as_echo_n "checking python extra libraries... " >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking python extra libraries" >&5
+printf %s "checking python extra libraries... " >&6; }
        if test -z "$PYTHON_EXTRA_LIBS"; then
-          PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
-                conf = distutils.sysconfig.get_config_var; \
-                print (conf('LIBS'))"`
+          PYTHON_EXTRA_LIBS=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                conf = sysconfig.get_config_var; \
+                print (conf('LIBS') + ' ' + conf('SYSLIBS'))"`
        fi
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_EXTRA_LIBS" >&5
-$as_echo "$PYTHON_EXTRA_LIBS" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_EXTRA_LIBS" >&5
+printf "%s\n" "$PYTHON_EXTRA_LIBS" >&6; }
 
 
        #
        # linking flags needed when embedding
        #
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking python extra linking flags" >&5
-$as_echo_n "checking python extra linking flags... " >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking python extra linking flags" >&5
+printf %s "checking python extra linking flags... " >&6; }
        if test -z "$PYTHON_EXTRA_LDFLAGS"; then
-               PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
-                       conf = distutils.sysconfig.get_config_var; \
+               PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                       conf = sysconfig.get_config_var; \
                        print (conf('LINKFORSHARED'))"`
        fi
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_EXTRA_LDFLAGS" >&5
-$as_echo "$PYTHON_EXTRA_LDFLAGS" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_EXTRA_LDFLAGS" >&5
+printf "%s\n" "$PYTHON_EXTRA_LDFLAGS" >&6; }
 
 
        #
        # final check to see if everything compiles alright
        #
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking consistency of all components of python development environment" >&5
-$as_echo_n "checking consistency of all components of python development environment... " >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking consistency of all components of python development environment" >&5
+printf %s "checking consistency of all components of python development environment... " >&6; }
        # save current global flags
        ac_save_LIBS="$LIBS"
+       ac_save_LDFLAGS="$LDFLAGS"
        ac_save_CPPFLAGS="$CPPFLAGS"
-       LIBS="$ac_save_LIBS $PYTHON_LDFLAGS $PYTHON_EXTRA_LDFLAGS $PYTHON_EXTRA_LIBS"
+       LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_EXTRA_LIBS"
+       LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS"
        CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
        ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -18297,7 +19862,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
                #include <Python.h>
 int
-main ()
+main (void)
 {
 Py_Initialize();
   ;
@@ -18305,12 +19870,13 @@ Py_Initialize();
 }
 
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   pythonexists=yes
-else
+else $as_nop
   pythonexists=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
        ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -18321,50 +19887,33 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
        # turn back to default flags
        CPPFLAGS="$ac_save_CPPFLAGS"
        LIBS="$ac_save_LIBS"
+       LDFLAGS="$ac_save_LDFLAGS"
 
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pythonexists" >&5
-$as_echo "$pythonexists" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $pythonexists" >&5
+printf "%s\n" "$pythonexists" >&6; }
 
         if test ! "x$pythonexists" = "xyes"; then
-          { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
-  Could not link test program to Python. Maybe the main Python library has been
-  installed in some non-standard library path. If so, pass it to configure,
-  via the LDFLAGS environment variable.
-  Example: ./configure LDFLAGS=\"-L/usr/non-standard-path/python/lib\"
-  ============================================================================
-   ERROR!
-   You probably have to install the development version of the Python package
-   for your distribution.  The exact name of this package varies among them.
-  ============================================================================
-          " >&5
-$as_echo "$as_me: WARNING:
+          { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
   Could not link test program to Python. Maybe the main Python library has been
   installed in some non-standard library path. If so, pass it to configure,
-  via the LDFLAGS environment variable.
-  Example: ./configure LDFLAGS=\"-L/usr/non-standard-path/python/lib\"
+  via the LIBS environment variable.
+  Example: ./configure LIBS=\"-L/usr/non-standard-path/python/lib\"
   ============================================================================
    ERROR!
    You probably have to install the development version of the Python package
    for your distribution.  The exact name of this package varies among them.
   ============================================================================
-          " >&2;}
+
+See \`config.log' for more details" "$LINENO" 5; }
          PYTHON_VERSION=""
-          no_python_devel=yes
        fi
 
        #
        # all done!
        #
 
-fi # AS_IF
-
-if test -z "$no_python_devel"; then :
-  have_python_dev=yes
-else
-  have_python_dev=no
-fi
-
-
 fi
 
 if test "x${cython_path}" = "x"; then
@@ -18372,11 +19921,12 @@ if test "x${cython_path}" = "x"; then
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CYTHON+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CYTHON+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CYTHON"; then
   ac_cv_prog_CYTHON="$CYTHON" # Let the user override the test.
 else
@@ -18384,11 +19934,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CYTHON="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 CYTHON=$ac_cv_prog_CYTHON
 if test -n "$CYTHON"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYTHON" >&5
-$as_echo "$CYTHON" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CYTHON" >&5
+printf "%s\n" "$CYTHON" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
 
 if test "x$GCC" = "xyes" -o "x$CC" = "xclang" ; then
 
-$as_echo "#define NGHTTP2_NORETURN __attribute__((noreturn))" >>confdefs.h
+printf "%s\n" "#define NGHTTP2_NORETURN __attribute__((noreturn))" >>confdefs.h
 
 else
 
-$as_echo "#define NGHTTP2_NORETURN /**/" >>confdefs.h
+printf "%s\n" "#define NGHTTP2_NORETURN /**/" >>confdefs.h
 
 fi
 
@@ -18441,12 +19995,13 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
     if test x$ac_success = xno; then
                 for alternative in ${ax_cxx_compile_alternatives}; do
       for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
-        cachevar=`$as_echo "ax_cv_cxx_compile_cxx14_$switch" | $as_tr_sh`
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++14 features with $switch" >&5
-$as_echo_n "checking whether $CXX supports C++14 features with $switch... " >&6; }
-if eval \${$cachevar+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+        cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx14_$switch" | $as_tr_sh`
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++14 features with $switch" >&5
+printf %s "checking whether $CXX supports C++14 features with $switch... " >&6; }
+if eval test \${$cachevar+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_save_CXX="$CXX"
            CXX="$CXX $switch"
            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -18858,17 +20413,18 @@ namespace cxx14
 
 
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   eval $cachevar=yes
-else
+else $as_nop
   eval $cachevar=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
            CXX="$ac_save_CXX"
 fi
 eval ac_res=\$$cachevar
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
         if eval test x\$$cachevar = xyes; then
           CXX="$CXX $switch"
           if test -n "$CXXCPP" ; then
@@ -18889,221 +20445,945 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-  if test x$ax_cxx_compile_cxx14_required = xtrue; then
-    if test x$ac_success = xno; then
-      as_fn_error $? "*** A compiler with support for C++14 language features is required." "$LINENO" 5
+  if test x$ax_cxx_compile_cxx14_required = xtrue; then
+    if test x$ac_success = xno; then
+      as_fn_error $? "*** A compiler with support for C++14 language features is required." "$LINENO" 5
+    fi
+  fi
+  if test x$ac_success = xno; then
+    HAVE_CXX14=0
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++14 support was found" >&5
+printf "%s\n" "$as_me: No compiler with C++14 support was found" >&6;}
+  else
+    HAVE_CXX14=1
+
+printf "%s\n" "#define HAVE_CXX14 1" >>confdefs.h
+
+  fi
+
+
+
+CXX1XCXXFLAGS="$CXXFLAGS"
+CXXFLAGS="$save_CXXFLAGS"
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS="$CXXFLAGS $CXX1XCXXFLAGS"
+
+# Check that std::future is available.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether std::future is available" >&5
+printf %s "checking whether std::future is available... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <vector>
+#include <future>
+
+int
+main (void)
+{
+
+std::vector<std::future<int>> v;
+(void)v;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+
+printf "%s\n" "#define HAVE_STD_FUTURE 1" >>confdefs.h
+
+     have_std_future=yes
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+else $as_nop
+  have_std_future=no
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+
+# Check that std::map::emplace is available for g++-4.7.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether std::map::emplace is available" >&5
+printf %s "checking whether std::map::emplace is available... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <map>
+
+int
+main (void)
+{
+
+std::map<int, int>().emplace(1, 2);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+
+printf "%s\n" "#define HAVE_STD_MAP_EMPLACE 1" >>confdefs.h
+
+     have_std_map_emplace=yes
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+else $as_nop
+  have_std_map_emplace=no
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+
+# Check that std::atomic_* overloads for std::shared_ptr are
+# available.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether std::atomic_* overloads for std::shared_ptr are available" >&5
+printf %s "checking whether std::atomic_* overloads for std::shared_ptr are available... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <memory>
+
+int
+main (void)
+{
+
+auto a = std::make_shared<int>(1000000007);
+auto p = std::atomic_load(&a);
+++*p;
+std::atomic_store(&a, p);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+
+printf "%s\n" "#define HAVE_ATOMIC_STD_SHARED_PTR 1" >>confdefs.h
+
+     have_atomic_std_shared_ptr=yes
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+else $as_nop
+  have_atomic_std_shared_ptr=no
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+
+# Check that thread_local storage specifier is available
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether thread_local storage class specifier is available." >&5
+printf %s "checking whether thread_local storage class specifier is available.... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+thread_local int a = 0;
+(void)a;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+
+printf "%s\n" "#define HAVE_THREAD_LOCAL 1" >>confdefs.h
+
+     have_thread_local=yes
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+else $as_nop
+  have_Thread_local=no
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+
+CXXFLAGS=$save_CXXFLAGS
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Checks for libraries.
+
+# Additional libraries required for tests.
+TESTLDADD=
+
+# Additional libraries required for programs under src directory.
+APPLDFLAGS=
+
+case "$host_os" in
+  *android*)
+    android_build=yes
+    # android does not need -pthread, but needs followng 3 libs for C++
+    APPLDFLAGS="$APPLDFLAGS -lstdc++ -latomic -lsupc++"
+    ;;
+  *)
+    PTHREAD_LDFLAGS="-pthread"
+    APPLDFLAGS="$APPLDFLAGS $PTHREAD_LDFLAGS"
+    ;;
+esac
+
+case "$host_os" in
+  *solaris*)
+    APPLDFLAGS="$APPLDFLAGS -lsocket -lnsl"
+    ;;
+esac
+
+case "${build}" in
+  *-apple-darwin*)
+    EXTRA_DEFS="-D__APPLE_USE_RFC_3542"
+
+    ;;
+esac
+
+# zlib
+have_zlib=no
+if test "x${request_zlib}" != "xno"; then
+
+pkg_failed=no
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib >= 1.2.3" >&5
+printf %s "checking for zlib >= 1.2.3... " >&6; }
+
+if test -n "$ZLIB_CFLAGS"; then
+    pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.3\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.3") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib >= 1.2.3" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$ZLIB_LIBS"; then
+    pkg_cv_ZLIB_LIBS="$ZLIB_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.3\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.3") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib >= 1.2.3" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.3" 2>&1`
+        else
+               ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.3" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$ZLIB_PKG_ERRORS" >&5
+
+       have_zlib=no
+elif test $pkg_failed = untried; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       have_zlib=no
+else
+       ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS
+       ZLIB_LIBS=$pkg_cv_ZLIB_LIBS
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       have_zlib=yes
+fi
+
+  if test "x${have_zlib}" = "xno"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ZLIB_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $ZLIB_PKG_ERRORS" >&6;}
+  fi
+fi
+
+if test "x${request_zlib}" = "xyes" &&
+   test "x${have_zlib}" != "xyes"; then
+  as_fn_error $? "zlib was requested (--with-zlib) but not found" "$LINENO" 5
+fi
+
+# dl: openssl requires libdl when it is statically linked.
+case "${host_os}" in
+  *bsd*)
+    # dlopen is in libc on *BSD
+    ;;
+  *)
+    save_LIBS=$LIBS
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
+printf %s "checking for library containing dlopen... " >&6; }
+if test ${ac_cv_search_dlopen+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main (void)
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' dl
+do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_search_dlopen=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext
+  if test ${ac_cv_search_dlopen+y}
+then :
+  break
+fi
+done
+if test ${ac_cv_search_dlopen+y}
+then :
+
+else $as_nop
+  ac_cv_search_dlopen=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5
+printf "%s\n" "$ac_cv_search_dlopen" >&6; }
+ac_res=$ac_cv_search_dlopen
+if test "$ac_res" != no
+then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+  APPLDFLAGS="-ldl $APPLDFLAGS"
+fi
+
+    LIBS=$save_LIBS
+    ;;
+esac
+
+# cunit
+have_cunit=no
+if test "x${request_cunit}" != "xno"; then
+
+pkg_failed=no
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cunit >= 2.1" >&5
+printf %s "checking for cunit >= 2.1... " >&6; }
+
+if test -n "$CUNIT_CFLAGS"; then
+    pkg_cv_CUNIT_CFLAGS="$CUNIT_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cunit >= 2.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "cunit >= 2.1") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_CUNIT_CFLAGS=`$PKG_CONFIG --cflags "cunit >= 2.1" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$CUNIT_LIBS"; then
+    pkg_cv_CUNIT_LIBS="$CUNIT_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cunit >= 2.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "cunit >= 2.1") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_CUNIT_LIBS=`$PKG_CONFIG --libs "cunit >= 2.1" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               CUNIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "cunit >= 2.1" 2>&1`
+        else
+               CUNIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "cunit >= 2.1" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$CUNIT_PKG_ERRORS" >&5
+
+       have_cunit=no
+elif test $pkg_failed = untried; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       have_cunit=no
+else
+       CUNIT_CFLAGS=$pkg_cv_CUNIT_CFLAGS
+       CUNIT_LIBS=$pkg_cv_CUNIT_LIBS
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       have_cunit=yes
+fi
+  # If pkg-config does not find cunit, check it using AC_CHECK_LIB.  We
+  # do this because Debian (Ubuntu) lacks pkg-config file for cunit.
+  if test "x${have_cunit}" = "xno"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: ${CUNIT_PKG_ERRORS}" >&5
+printf "%s\n" "$as_me: WARNING: ${CUNIT_PKG_ERRORS}" >&2;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CU_initialize_registry in -lcunit" >&5
+printf %s "checking for CU_initialize_registry in -lcunit... " >&6; }
+if test ${ac_cv_lib_cunit_CU_initialize_registry+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcunit  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char CU_initialize_registry ();
+int
+main (void)
+{
+return CU_initialize_registry ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_lib_cunit_CU_initialize_registry=yes
+else $as_nop
+  ac_cv_lib_cunit_CU_initialize_registry=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cunit_CU_initialize_registry" >&5
+printf "%s\n" "$ac_cv_lib_cunit_CU_initialize_registry" >&6; }
+if test "x$ac_cv_lib_cunit_CU_initialize_registry" = xyes
+then :
+  have_cunit=yes
+else $as_nop
+  have_cunit=no
+fi
+
+    if test "x${have_cunit}" = "xyes"; then
+      CUNIT_LIBS="-lcunit"
+      CUNIT_CFLAGS=""
+
+
+    fi
+  fi
+  if test "x${have_cunit}" = "xyes"; then
+    # cunit in Mac OS X requires ncurses. Note that in Mac OS X, test
+    # program can be built without -lncurses, but it emits runtime
+    # error.
+    case "${build}" in
+      *-apple-darwin*)
+        CUNIT_LIBS="$CUNIT_LIBS -lncurses"
+
+        ;;
+    esac
+  fi
+fi
+
+if test "x${request_cunit}" = "xyes" &&
+   test "x${have_cunit}" != "xyes"; then
+  as_fn_error $? "cunit was requested (--with-cunit) but not found" "$LINENO" 5
+fi
+
+ if  test "x${have_cunit}" = "xyes" ; then
+  HAVE_CUNIT_TRUE=
+  HAVE_CUNIT_FALSE='#'
+else
+  HAVE_CUNIT_TRUE='#'
+  HAVE_CUNIT_FALSE=
+fi
+
+
+# libev (for src)
+have_libev=no
+if test "x${request_libev}" != "xno"; then
+  if test "x${LIBEV_LIBS}" = "x" && test "x${LIBEV_CFLAGS}" = "x"; then
+    # libev does not have pkg-config file.  Check it in an old way.
+    save_LIBS=$LIBS
+    # android requires -lm for floor
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ev_time in -lev" >&5
+printf %s "checking for ev_time in -lev... " >&6; }
+if test ${ac_cv_lib_ev_ev_time+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lev -lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char ev_time ();
+int
+main (void)
+{
+return ev_time ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_lib_ev_ev_time=yes
+else $as_nop
+  ac_cv_lib_ev_ev_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ev_ev_time" >&5
+printf "%s\n" "$ac_cv_lib_ev_ev_time" >&6; }
+if test "x$ac_cv_lib_ev_ev_time" = xyes
+then :
+  have_libev=yes
+else $as_nop
+  have_libev=no
+fi
+
+   if test "x${have_libev}" = "xyes"; then
+      ac_fn_c_check_header_compile "$LINENO" "ev.h" "ac_cv_header_ev_h" "$ac_includes_default"
+if test "x$ac_cv_header_ev_h" = xyes
+then :
+  have_libev=yes
+else $as_nop
+  have_libev=no
+fi
+
+      if test "x${have_libev}" = "xyes"; then
+        LIBEV_LIBS=-lev
+        LIBEV_CFLAGS=
+      fi
     fi
-  fi
-  if test x$ac_success = xno; then
-    HAVE_CXX14=0
-    { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++14 support was found" >&5
-$as_echo "$as_me: No compiler with C++14 support was found" >&6;}
+    LIBS=$save_LIBS
   else
-    HAVE_CXX14=1
-
-$as_echo "#define HAVE_CXX14 1" >>confdefs.h
-
+    have_libev=yes
   fi
+fi
 
+if test "x${request_libev}" = "xyes" &&
+   test "x${have_libev}" != "xyes"; then
+  as_fn_error $? "libev was requested (--with-libev) but not found" "$LINENO" 5
+fi
 
+# openssl (for src)
+have_openssl=no
+if test "x${request_openssl}" != "xno"; then
 
-CXX1XCXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$save_CXXFLAGS"
+pkg_failed=no
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for openssl >= 1.0.1" >&5
+printf %s "checking for openssl >= 1.0.1... " >&6; }
 
+if test -n "$OPENSSL_CFLAGS"; then
+    pkg_cv_OPENSSL_CFLAGS="$OPENSSL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl >= 1.0.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "openssl >= 1.0.1") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_OPENSSL_CFLAGS=`$PKG_CONFIG --cflags "openssl >= 1.0.1" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$OPENSSL_LIBS"; then
+    pkg_cv_OPENSSL_LIBS="$OPENSSL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl >= 1.0.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "openssl >= 1.0.1") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_OPENSSL_LIBS=`$PKG_CONFIG --libs "openssl >= 1.0.1" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
 
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
 
-save_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS $CXX1XCXXFLAGS"
+if test $pkg_failed = yes; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
-# Check that std::future is available.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether std::future is available" >&5
-$as_echo_n "checking whether std::future is available... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               OPENSSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "openssl >= 1.0.1" 2>&1`
+        else
+               OPENSSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "openssl >= 1.0.1" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$OPENSSL_PKG_ERRORS" >&5
+
+       have_openssl=no
+elif test $pkg_failed = untried; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       have_openssl=no
+else
+       OPENSSL_CFLAGS=$pkg_cv_OPENSSL_CFLAGS
+       OPENSSL_LIBS=$pkg_cv_OPENSSL_LIBS
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       have_openssl=yes
+fi
+  if test "x${have_openssl}" = "xno"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $OPENSSL_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $OPENSSL_PKG_ERRORS" >&6;}
+  else
+    save_CFLAGS="$CFLAGS"
+    save_LIBS="$LIBS"
+    CFLAGS="$OPENSSL_CFLAGS $CFLAGS"
+    LIBS="$OPENSSL_LIBS $LIBS"
+
+    # quictls/openssl has SSL_is_quic.
+    have_ssl_is_quic=no
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SSL_is_quic" >&5
+printf %s "checking for SSL_is_quic... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-#include <vector>
-#include <future>
+      #include <openssl/ssl.h>
 
 int
-main ()
+main (void)
 {
 
-std::vector<std::future<int>> v;
+      SSL *ssl = NULL;
+      SSL_is_quic(ssl);
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-
-$as_echo "#define HAVE_STD_FUTURE 1" >>confdefs.h
-
-     have_std_future=yes
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
-  have_std_future=no
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+if ac_fn_c_try_link "$LINENO"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }; have_ssl_is_quic=yes
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }; have_ssl_is_quic=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
 
-# Check that std::map::emplace is available for g++-4.7.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether std::map::emplace is available" >&5
-$as_echo_n "checking whether std::map::emplace is available... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+    # boringssl has SSL_set_quic_early_data_context.
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SSL_set_quic_early_data_context" >&5
+printf %s "checking for SSL_set_quic_early_data_context... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-#include <map>
+      #include <openssl/ssl.h>
 
 int
-main ()
+main (void)
 {
 
-std::map<int, int>().emplace(1, 2);
+      SSL *ssl = NULL;
+      SSL_set_quic_early_data_context(ssl, NULL, 0);
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }; have_boringssl_quic=yes
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }; have_boringssl_quic=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
 
-$as_echo "#define HAVE_STD_MAP_EMPLACE 1" >>confdefs.h
+    CFLAGS="$save_CFLAGS"
+    LIBS="$save_LIBS"
+  fi
+fi
 
-     have_std_map_emplace=yes
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
-  have_std_map_emplace=no
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+if test "x${request_openssl}" = "xyes" &&
+   test "x${have_openssl}" != "xyes"; then
+  as_fn_error $? "openssl was requested (--with-openssl) but not found" "$LINENO" 5
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
-# Check that std::atomic_* overloads for std::shared_ptr are
-# available.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether std::atomic_* overloads for std::shared_ptr are available" >&5
-$as_echo_n "checking whether std::atomic_* overloads for std::shared_ptr are available... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+# c-ares (for src)
+have_libcares=no
+if test "x${request_libcares}" != "xno"; then
 
-#include <memory>
+pkg_failed=no
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libcares >= 1.7.5" >&5
+printf %s "checking for libcares >= 1.7.5... " >&6; }
 
-int
-main ()
-{
+if test -n "$LIBCARES_CFLAGS"; then
+    pkg_cv_LIBCARES_CFLAGS="$LIBCARES_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcares >= 1.7.5\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libcares >= 1.7.5") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBCARES_CFLAGS=`$PKG_CONFIG --cflags "libcares >= 1.7.5" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$LIBCARES_LIBS"; then
+    pkg_cv_LIBCARES_LIBS="$LIBCARES_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcares >= 1.7.5\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libcares >= 1.7.5") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBCARES_LIBS=`$PKG_CONFIG --libs "libcares >= 1.7.5" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
 
-auto a = std::make_shared<int>(1000000007);
-auto p = std::atomic_load(&a);
-++*p;
-std::atomic_store(&a, p);
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
 
-$as_echo "#define HAVE_ATOMIC_STD_SHARED_PTR 1" >>confdefs.h
+if test $pkg_failed = yes; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
-     have_atomic_std_shared_ptr=yes
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
 else
-  have_atomic_std_shared_ptr=no
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        _pkg_short_errors_supported=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-# Check that thread_local storage specifier is available
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether thread_local storage class specifier is available." >&5
-$as_echo_n "checking whether thread_local storage class specifier is available.... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+        if test $_pkg_short_errors_supported = yes; then
+               LIBCARES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcares >= 1.7.5" 2>&1`
+        else
+               LIBCARES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcares >= 1.7.5" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$LIBCARES_PKG_ERRORS" >&5
 
-int
-main ()
-{
+       have_libcares=no
+elif test $pkg_failed = untried; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       have_libcares=no
+else
+       LIBCARES_CFLAGS=$pkg_cv_LIBCARES_CFLAGS
+       LIBCARES_LIBS=$pkg_cv_LIBCARES_LIBS
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       have_libcares=yes
+fi
+  if test "x${have_libcares}" = "xno"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $LIBCARES_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $LIBCARES_PKG_ERRORS" >&6;}
+  fi
+fi
 
-thread_local int a = 0;
-(void)a;
+if test "x${request_libcares}" = "xyes" &&
+   test "x${have_libcares}" != "xyes"; then
+  as_fn_error $? "libcares was requested (--with-libcares) but not found" "$LINENO" 5
+fi
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+# ngtcp2 (for src)
+have_libngtcp2=no
+if test "x${request_libngtcp2}" != "xno"; then
 
-$as_echo "#define HAVE_THREAD_LOCAL 1" >>confdefs.h
+pkg_failed=no
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2 >= 0.0.0" >&5
+printf %s "checking for libngtcp2 >= 0.0.0... " >&6; }
 
-     have_thread_local=yes
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+if test -n "$LIBNGTCP2_CFLAGS"; then
+    pkg_cv_LIBNGTCP2_CFLAGS="$LIBNGTCP2_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libngtcp2 >= 0.0.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libngtcp2 >= 0.0.0") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBNGTCP2_CFLAGS=`$PKG_CONFIG --cflags "libngtcp2 >= 0.0.0" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
 else
-  have_Thread_local=no
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$LIBNGTCP2_LIBS"; then
+    pkg_cv_LIBNGTCP2_LIBS="$LIBNGTCP2_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libngtcp2 >= 0.0.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libngtcp2 >= 0.0.0") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBNGTCP2_LIBS=`$PKG_CONFIG --libs "libngtcp2 >= 0.0.0" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-CXXFLAGS=$save_CXXFLAGS
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
 
-# Checks for libraries.
 
-# Additional libraries required for tests.
-TESTLDADD=
 
-# Additional libraries required for programs under src directory.
-APPLDFLAGS=
+if test $pkg_failed = yes; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
-case "$host_os" in
-  *android*)
-    android_build=yes
-    # android does not need -pthread, but needs followng 3 libs for C++
-    APPLDFLAGS="$APPLDFLAGS -lstdc++ -latomic -lsupc++"
-    ;;
-  *)
-    PTHREAD_LDFLAGS="-pthread"
-    APPLDFLAGS="$APPLDFLAGS $PTHREAD_LDFLAGS"
-    ;;
-esac
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               LIBNGTCP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libngtcp2 >= 0.0.0" 2>&1`
+        else
+               LIBNGTCP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libngtcp2 >= 0.0.0" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$LIBNGTCP2_PKG_ERRORS" >&5
 
-case "$host_os" in
-  *solaris*)
-    APPLDFLAGS="$APPLDFLAGS -lsocket -lnsl"
-    ;;
-esac
+       have_libngtcp2=no
+elif test $pkg_failed = untried; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       have_libngtcp2=no
+else
+       LIBNGTCP2_CFLAGS=$pkg_cv_LIBNGTCP2_CFLAGS
+       LIBNGTCP2_LIBS=$pkg_cv_LIBNGTCP2_LIBS
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       have_libngtcp2=yes
+fi
+  if test "x${have_libngtcp2}" = "xno"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $LIBNGTCP2_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $LIBNGTCP2_PKG_ERRORS" >&6;}
+  fi
+fi
 
-# zlib
+if test "x${request_libngtcp2}" = "xyes" &&
+   test "x${have_libngtcp2}" != "xyes"; then
+  as_fn_error $? "libngtcp2 was requested (--with-libngtcp2) but not found" "$LINENO" 5
+fi
+
+# ngtcp2_crypto_openssl (for src)
+have_libngtcp2_crypto_openssl=no
+if test "x${have_ssl_is_quic}" = "xyes" &&
+   test "x${request_libngtcp2}" != "xno"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ZLIB" >&5
-$as_echo_n "checking for ZLIB... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2_crypto_openssl >= 0.0.0" >&5
+printf %s "checking for libngtcp2_crypto_openssl >= 0.0.0... " >&6; }
 
-if test -n "$ZLIB_CFLAGS"; then
-    pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS"
+if test -n "$LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS"; then
+    pkg_cv_LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS="$LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.3\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.3") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libngtcp2_crypto_openssl >= 0.0.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libngtcp2_crypto_openssl >= 0.0.0") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib >= 1.2.3" 2>/dev/null`
+  pkg_cv_LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS=`$PKG_CONFIG --cflags "libngtcp2_crypto_openssl >= 0.0.0" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
  else
     pkg_failed=untried
 fi
-if test -n "$ZLIB_LIBS"; then
-    pkg_cv_ZLIB_LIBS="$ZLIB_LIBS"
+if test -n "$LIBNGTCP2_CRYPTO_OPENSSL_LIBS"; then
+    pkg_cv_LIBNGTCP2_CRYPTO_OPENSSL_LIBS="$LIBNGTCP2_CRYPTO_OPENSSL_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.3\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.3") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libngtcp2_crypto_openssl >= 0.0.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libngtcp2_crypto_openssl >= 0.0.0") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib >= 1.2.3" 2>/dev/null`
+  pkg_cv_LIBNGTCP2_CRYPTO_OPENSSL_LIBS=`$PKG_CONFIG --libs "libngtcp2_crypto_openssl >= 0.0.0" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -19132,8 +21412,8 @@ fi
 
 
 if test $pkg_failed = yes; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
@@ -19141,114 +21421,60 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-               ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.3" 2>&1`
+               LIBNGTCP2_CRYPTO_OPENSSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libngtcp2_crypto_openssl >= 0.0.0" 2>&1`
         else
-               ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.3" 2>&1`
+               LIBNGTCP2_CRYPTO_OPENSSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libngtcp2_crypto_openssl >= 0.0.0" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
-       echo "$ZLIB_PKG_ERRORS" >&5
+       echo "$LIBNGTCP2_CRYPTO_OPENSSL_PKG_ERRORS" >&5
 
-       have_zlib=no
+       have_libngtcp2_crypto_openssl=no
 elif test $pkg_failed = untried; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-       have_zlib=no
-else
-       ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS
-       ZLIB_LIBS=$pkg_cv_ZLIB_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-       have_zlib=yes
-fi
-
-if test "x${have_zlib}" = "xno"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: $ZLIB_PKG_ERRORS" >&5
-$as_echo "$as_me: $ZLIB_PKG_ERRORS" >&6;}
-fi
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       have_libngtcp2_crypto_openssl=no
+else
+       LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS=$pkg_cv_LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS
+       LIBNGTCP2_CRYPTO_OPENSSL_LIBS=$pkg_cv_LIBNGTCP2_CRYPTO_OPENSSL_LIBS
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       have_libngtcp2_crypto_openssl=yes
+fi
+  if test "x${have_libngtcp2_crypto_openssl}" = "xno"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $LIBNGTCP2_CRYPTO_OPENSSL_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $LIBNGTCP2_CRYPTO_OPENSSL_PKG_ERRORS" >&6;}
+  else
 
-# dl: openssl requires libdl when it is statically linked.
-case "${host_os}" in
-  *bsd*)
-    # dlopen is in libc on *BSD
-    ;;
-  *)
-    save_LIBS=$LIBS
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
-$as_echo_n "checking for library containing dlopen... " >&6; }
-if ${ac_cv_search_dlopen+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+printf "%s\n" "#define HAVE_LIBNGTCP2_CRYPTO_OPENSSL 1" >>confdefs.h
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
-  ;
-  return 0;
-}
-_ACEOF
-for ac_lib in '' dl; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_dlopen=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_dlopen+:} false; then :
-  break
 fi
-done
-if ${ac_cv_search_dlopen+:} false; then :
 
-else
-  ac_cv_search_dlopen=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5
-$as_echo "$ac_cv_search_dlopen" >&6; }
-ac_res=$ac_cv_search_dlopen
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-  APPLDFLAGS="-ldl $APPLDFLAGS"
+if test "x${have_ssl_is_quic}" = "xyes" &&
+   test "x${request_libngtcp2}" = "xyes" &&
+   test "x${have_libngtcp2_crypto_openssl}" != "xyes"; then
+  as_fn_error $? "libngtcp2_crypto_openssl was requested (--with-libngtcp2) but not found" "$LINENO" 5
 fi
 
-    LIBS=$save_LIBS
-    ;;
-esac
-
-# cunit
+# ngtcp2_crypto_boringssl (for src)
+have_libngtcp2_crypto_boringssl=no
+if test "x${have_boringssl_quic}" = "xyes" &&
+   test "x${request_libngtcp2}" != "xno"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CUNIT" >&5
-$as_echo_n "checking for CUNIT... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2_crypto_boringssl >= 0.0.0" >&5
+printf %s "checking for libngtcp2_crypto_boringssl >= 0.0.0... " >&6; }
 
-if test -n "$CUNIT_CFLAGS"; then
-    pkg_cv_CUNIT_CFLAGS="$CUNIT_CFLAGS"
+if test -n "$LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS"; then
+    pkg_cv_LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS="$LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cunit >= 2.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "cunit >= 2.1") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libngtcp2_crypto_boringssl >= 0.0.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libngtcp2_crypto_boringssl >= 0.0.0") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_CUNIT_CFLAGS=`$PKG_CONFIG --cflags "cunit >= 2.1" 2>/dev/null`
+  pkg_cv_LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS=`$PKG_CONFIG --cflags "libngtcp2_crypto_boringssl >= 0.0.0" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
  else
     pkg_failed=untried
 fi
-if test -n "$CUNIT_LIBS"; then
-    pkg_cv_CUNIT_LIBS="$CUNIT_LIBS"
+if test -n "$LIBNGTCP2_CRYPTO_BORINGSSL_LIBS"; then
+    pkg_cv_LIBNGTCP2_CRYPTO_BORINGSSL_LIBS="$LIBNGTCP2_CRYPTO_BORINGSSL_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cunit >= 2.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "cunit >= 2.1") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libngtcp2_crypto_boringssl >= 0.0.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libngtcp2_crypto_boringssl >= 0.0.0") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_CUNIT_LIBS=`$PKG_CONFIG --libs "cunit >= 2.1" 2>/dev/null`
+  pkg_cv_LIBNGTCP2_CRYPTO_BORINGSSL_LIBS=`$PKG_CONFIG --libs "libngtcp2_crypto_boringssl >= 0.0.0" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -19277,8 +21503,8 @@ fi
 
 
 if test $pkg_failed = yes; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
@@ -19286,180 +21512,59 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-               CUNIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "cunit >= 2.1" 2>&1`
+               LIBNGTCP2_CRYPTO_BORINGSSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libngtcp2_crypto_boringssl >= 0.0.0" 2>&1`
         else
-               CUNIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "cunit >= 2.1" 2>&1`
+               LIBNGTCP2_CRYPTO_BORINGSSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libngtcp2_crypto_boringssl >= 0.0.0" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
-       echo "$CUNIT_PKG_ERRORS" >&5
+       echo "$LIBNGTCP2_CRYPTO_BORINGSSL_PKG_ERRORS" >&5
 
-       have_cunit=no
+       have_libngtcp2_crypto_boringssl=no
 elif test $pkg_failed = untried; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-       have_cunit=no
-else
-       CUNIT_CFLAGS=$pkg_cv_CUNIT_CFLAGS
-       CUNIT_LIBS=$pkg_cv_CUNIT_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-       have_cunit=yes
-fi
-# If pkg-config does not find cunit, check it using AC_CHECK_LIB.  We
-# do this because Debian (Ubuntu) lacks pkg-config file for cunit.
-if test "x${have_cunit}" = "xno"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ${CUNIT_PKG_ERRORS}" >&5
-$as_echo "$as_me: WARNING: ${CUNIT_PKG_ERRORS}" >&2;}
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CU_initialize_registry in -lcunit" >&5
-$as_echo_n "checking for CU_initialize_registry in -lcunit... " >&6; }
-if ${ac_cv_lib_cunit_CU_initialize_registry+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lcunit  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char CU_initialize_registry ();
-int
-main ()
-{
-return CU_initialize_registry ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_cunit_CU_initialize_registry=yes
-else
-  ac_cv_lib_cunit_CU_initialize_registry=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cunit_CU_initialize_registry" >&5
-$as_echo "$ac_cv_lib_cunit_CU_initialize_registry" >&6; }
-if test "x$ac_cv_lib_cunit_CU_initialize_registry" = xyes; then :
-  have_cunit=yes
-else
-  have_cunit=no
-fi
-
-  if test "x${have_cunit}" = "xyes"; then
-    CUNIT_LIBS="-lcunit"
-    CUNIT_CFLAGS=""
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       have_libngtcp2_crypto_boringssl=no
+else
+       LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS=$pkg_cv_LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS
+       LIBNGTCP2_CRYPTO_BORINGSSL_LIBS=$pkg_cv_LIBNGTCP2_CRYPTO_BORINGSSL_LIBS
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       have_libngtcp2_crypto_boringssl=yes
+fi
+  if test "x${have_libngtcp2_crypto_boringssl}" = "xno"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $LIBNGTCP2_CRYPTO_BORINGSSL_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $LIBNGTCP2_CRYPTO_BORINGSSL_PKG_ERRORS" >&6;}
+  else
 
+printf "%s\n" "#define HAVE_LIBNGTCP2_CRYPTO_BORINGSSL 1" >>confdefs.h
 
   fi
 fi
-if test "x${have_cunit}" = "xyes"; then
-  # cunit in Mac OS X requires ncurses. Note that in Mac OS X, test
-  # program can be built without -lncurses, but it emits runtime
-  # error.
-  case "${build}" in
-    *-apple-darwin*)
-      CUNIT_LIBS="$CUNIT_LIBS -lncurses"
-
-      ;;
-  esac
-fi
-
- if  test "x${have_cunit}" = "xyes" ; then
-  HAVE_CUNIT_TRUE=
-  HAVE_CUNIT_FALSE='#'
-else
-  HAVE_CUNIT_TRUE='#'
-  HAVE_CUNIT_FALSE=
-fi
-
-
-# libev (for src)
-# libev does not have pkg-config file.  Check it in an old way.
-save_LIBS=$LIBS
-# android requires -lm for floor
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ev_time in -lev" >&5
-$as_echo_n "checking for ev_time in -lev... " >&6; }
-if ${ac_cv_lib_ev_ev_time+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lev -lm $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ev_time ();
-int
-main ()
-{
-return ev_time ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_ev_ev_time=yes
-else
-  ac_cv_lib_ev_ev_time=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ev_ev_time" >&5
-$as_echo "$ac_cv_lib_ev_ev_time" >&6; }
-if test "x$ac_cv_lib_ev_ev_time" = xyes; then :
-  have_libev=yes
-else
-  have_libev=no
-fi
-
-if test "x${have_libev}" = "xyes"; then
-  ac_fn_c_check_header_mongrel "$LINENO" "ev.h" "ac_cv_header_ev_h" "$ac_includes_default"
-if test "x$ac_cv_header_ev_h" = xyes; then :
-  have_libev=yes
-else
-  have_libev=no
-fi
-
-
-  if test "x${have_libev}" = "xyes"; then
-    LIBEV_LIBS=-lev
-    LIBEV_CFLAGS=
 
-
-  fi
+if test "x${have_boringssl_quic}" = "xyes" &&
+   test "x${request_libngtcp2}" = "xyes" &&
+   test "x${have_libngtcp2_crypto_boringssl}" != "xyes"; then
+  as_fn_error $? "libngtcp2_crypto_boringssl was requested (--with-libngtcp2) but not found" "$LINENO" 5
 fi
-LIBS=$save_LIBS
 
-# openssl (for src)
+# nghttp3 (for src)
+have_libnghttp3=no
+if test "x${request_libnghttp3}" != "xno"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL" >&5
-$as_echo_n "checking for OPENSSL... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libnghttp3 >= 0.0.0" >&5
+printf %s "checking for libnghttp3 >= 0.0.0... " >&6; }
 
-if test -n "$OPENSSL_CFLAGS"; then
-    pkg_cv_OPENSSL_CFLAGS="$OPENSSL_CFLAGS"
+if test -n "$LIBNGHTTP3_CFLAGS"; then
+    pkg_cv_LIBNGHTTP3_CFLAGS="$LIBNGHTTP3_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl >= 1.0.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "openssl >= 1.0.1") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnghttp3 >= 0.0.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libnghttp3 >= 0.0.0") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_OPENSSL_CFLAGS=`$PKG_CONFIG --cflags "openssl >= 1.0.1" 2>/dev/null`
+  pkg_cv_LIBNGHTTP3_CFLAGS=`$PKG_CONFIG --cflags "libnghttp3 >= 0.0.0" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
  else
     pkg_failed=untried
 fi
-if test -n "$OPENSSL_LIBS"; then
-    pkg_cv_OPENSSL_LIBS="$OPENSSL_LIBS"
+if test -n "$LIBNGHTTP3_LIBS"; then
+    pkg_cv_LIBNGHTTP3_LIBS="$LIBNGHTTP3_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl >= 1.0.1\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "openssl >= 1.0.1") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnghttp3 >= 0.0.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libnghttp3 >= 0.0.0") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_OPENSSL_LIBS=`$PKG_CONFIG --libs "openssl >= 1.0.1" 2>/dev/null`
+  pkg_cv_LIBNGHTTP3_LIBS=`$PKG_CONFIG --libs "libnghttp3 >= 0.0.0" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -19488,8 +21593,8 @@ fi
 
 
 if test $pkg_failed = yes; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
@@ -19497,46 +21602,54 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-               OPENSSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "openssl >= 1.0.1" 2>&1`
+               LIBNGHTTP3_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnghttp3 >= 0.0.0" 2>&1`
         else
-               OPENSSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "openssl >= 1.0.1" 2>&1`
+               LIBNGHTTP3_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnghttp3 >= 0.0.0" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
-       echo "$OPENSSL_PKG_ERRORS" >&5
+       echo "$LIBNGHTTP3_PKG_ERRORS" >&5
 
-       have_openssl=no
+       have_libnghttp3=no
 elif test $pkg_failed = untried; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-       have_openssl=no
-else
-       OPENSSL_CFLAGS=$pkg_cv_OPENSSL_CFLAGS
-       OPENSSL_LIBS=$pkg_cv_OPENSSL_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-       have_openssl=yes
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       have_libnghttp3=no
+else
+       LIBNGHTTP3_CFLAGS=$pkg_cv_LIBNGHTTP3_CFLAGS
+       LIBNGHTTP3_LIBS=$pkg_cv_LIBNGHTTP3_LIBS
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       have_libnghttp3=yes
+fi
+  if test "x${have_libnghttp3}" = "xno"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $LIBNGHTTP3_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $LIBNGHTTP3_PKG_ERRORS" >&6;}
+  fi
 fi
-if test "x${have_openssl}" = "xno"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: $OPENSSL_PKG_ERRORS" >&5
-$as_echo "$as_me: $OPENSSL_PKG_ERRORS" >&6;}
+
+if test "x${request_libnghttp3}" = "xyes" &&
+   test "x${have_libnghttp3}" != "xyes"; then
+  as_fn_error $? "libnghttp3 was requested (--with-libnghttp3) but not found" "$LINENO" 5
 fi
 
-# c-ares (for src)
+# libbpf (for src)
+have_libbpf=no
+if test "x${request_libbpf}" != "xno"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBCARES" >&5
-$as_echo_n "checking for LIBCARES... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libbpf >= 0.4.0" >&5
+printf %s "checking for libbpf >= 0.4.0... " >&6; }
 
-if test -n "$LIBCARES_CFLAGS"; then
-    pkg_cv_LIBCARES_CFLAGS="$LIBCARES_CFLAGS"
+if test -n "$LIBBPF_CFLAGS"; then
+    pkg_cv_LIBBPF_CFLAGS="$LIBBPF_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcares >= 1.7.5\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libcares >= 1.7.5") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libbpf >= 0.4.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libbpf >= 0.4.0") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBCARES_CFLAGS=`$PKG_CONFIG --cflags "libcares >= 1.7.5" 2>/dev/null`
+  pkg_cv_LIBBPF_CFLAGS=`$PKG_CONFIG --cflags "libbpf >= 0.4.0" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
  else
     pkg_failed=untried
 fi
-if test -n "$LIBCARES_LIBS"; then
-    pkg_cv_LIBCARES_LIBS="$LIBCARES_LIBS"
+if test -n "$LIBBPF_LIBS"; then
+    pkg_cv_LIBBPF_LIBS="$LIBBPF_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcares >= 1.7.5\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libcares >= 1.7.5") 2>&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libbpf >= 0.4.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libbpf >= 0.4.0") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBCARES_LIBS=`$PKG_CONFIG --libs "libcares >= 1.7.5" 2>/dev/null`
+  pkg_cv_LIBBPF_LIBS=`$PKG_CONFIG --libs "libbpf >= 0.4.0" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -19565,8 +21678,8 @@ fi
 
 
 if test $pkg_failed = yes; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
@@ -19574,45 +21687,109 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-               LIBCARES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcares >= 1.7.5" 2>&1`
+               LIBBPF_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libbpf >= 0.4.0" 2>&1`
         else
-               LIBCARES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcares >= 1.7.5" 2>&1`
+               LIBBPF_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libbpf >= 0.4.0" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
-       echo "$LIBCARES_PKG_ERRORS" >&5
+       echo "$LIBBPF_PKG_ERRORS" >&5
 
-       have_libcares=no
+       have_libbpf=no
 elif test $pkg_failed = untried; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-       have_libcares=no
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       have_libbpf=no
 else
-       LIBCARES_CFLAGS=$pkg_cv_LIBCARES_CFLAGS
-       LIBCARES_LIBS=$pkg_cv_LIBCARES_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-       have_libcares=yes
+       LIBBPF_CFLAGS=$pkg_cv_LIBBPF_CFLAGS
+       LIBBPF_LIBS=$pkg_cv_LIBBPF_LIBS
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       have_libbpf=yes
+fi
+  if test "x${have_libbpf}" = "xyes"; then
+
+printf "%s\n" "#define HAVE_LIBBPF 1" >>confdefs.h
+
+    if test "x${BPFCFLAGS}" = "x"; then
+      BPFCFLAGS="-Wall -O2 -g"
+    fi
+    # Add the include path for Debian
+    EXTRABPFCFLAGS="-I/usr/include/$host_cpu-$host_os"
+
+
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether enum bpf_stats_type is defined in linux/bpf.h" >&5
+printf %s "checking whether enum bpf_stats_type is defined in linux/bpf.h... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+    #include <linux/bpf.h>
+
+int
+main (void)
+{
+
+    enum bpf_stats_type foo;
+    (void)foo;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  have_bpf_stats_type=yes
+else $as_nop
+  have_bpf_stats_type=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+
+    if test "x${have_bpf_stats_type}" = "xyes"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+
+printf "%s\n" "#define HAVE_BPF_STATS_TYPE 1" >>confdefs.h
+
+    else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+    fi
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $LIBBPF_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $LIBBPF_PKG_ERRORS" >&6;}
+  fi
+fi
+
+if test "x${request_libbpf}" = "xyes" &&
+   test "x${have_libbpf}" != "xyes"; then
+  as_fn_error $? "libbpf was requested (--with-libbpf) but not found" "$LINENO" 5
 fi
-if test "x${have_libcares}" = "xno"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: $LIBCARES_PKG_ERRORS" >&5
-$as_echo "$as_me: $LIBCARES_PKG_ERRORS" >&6;}
+
+ if  test "x${have_libbpf}" = "xyes" ; then
+  HAVE_LIBBPF_TRUE=
+  HAVE_LIBBPF_FALSE='#'
+else
+  HAVE_LIBBPF_TRUE='#'
+  HAVE_LIBBPF_FALSE=
 fi
 
+
 # libevent_openssl (for examples)
 # 2.0.8 is required because we use evconnlistener_set_error_cb()
+have_libevent_openssl=no
+if test "x${request_libevent_openssl}" != "xno"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBEVENT_OPENSSL" >&5
-$as_echo_n "checking for LIBEVENT_OPENSSL... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libevent_openssl >= 2.0.8" >&5
+printf %s "checking for libevent_openssl >= 2.0.8... " >&6; }
 
 if test -n "$LIBEVENT_OPENSSL_CFLAGS"; then
     pkg_cv_LIBEVENT_OPENSSL_CFLAGS="$LIBEVENT_OPENSSL_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libevent_openssl >= 2.0.8\""; } >&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libevent_openssl >= 2.0.8\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libevent_openssl >= 2.0.8") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_LIBEVENT_OPENSSL_CFLAGS=`$PKG_CONFIG --cflags "libevent_openssl >= 2.0.8" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
@@ -19626,10 +21803,10 @@ if test -n "$LIBEVENT_OPENSSL_LIBS"; then
     pkg_cv_LIBEVENT_OPENSSL_LIBS="$LIBEVENT_OPENSSL_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libevent_openssl >= 2.0.8\""; } >&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libevent_openssl >= 2.0.8\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libevent_openssl >= 2.0.8") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_LIBEVENT_OPENSSL_LIBS=`$PKG_CONFIG --libs "libevent_openssl >= 2.0.8" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
@@ -19643,8 +21820,8 @@ fi
 
 
 if test $pkg_failed = yes; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
 
        have_libevent_openssl=no
 elif test $pkg_failed = untried; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
        have_libevent_openssl=no
 else
        LIBEVENT_OPENSSL_CFLAGS=$pkg_cv_LIBEVENT_OPENSSL_CFLAGS
        LIBEVENT_OPENSSL_LIBS=$pkg_cv_LIBEVENT_OPENSSL_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
        have_libevent_openssl=yes
 fi
-if test "x${have_libevent_openssl}" = "xno"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: $LIBEVENT_OPENSSL_PKG_ERRORS" >&5
-$as_echo "$as_me: $LIBEVENT_OPENSSL_PKG_ERRORS" >&6;}
+  if test "x${have_libevent_openssl}" = "xno"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $LIBEVENT_OPENSSL_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $LIBEVENT_OPENSSL_PKG_ERRORS" >&6;}
+  fi
+fi
+
+if test "x${request_libevent_openssl}" = "xyes" &&
+   test "x${have_libevent_openssl}" != "xyes"; then
+  as_fn_error $? "libevent_openssl was requested (--with-libevent) but not found" "$LINENO" 5
 fi
 
 # jansson (for src/nghttp, src/deflatehd and src/inflatehd)
+have_jansson=no
+if test "x${request_jansson}" != "xno"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JANSSON" >&5
-$as_echo_n "checking for JANSSON... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for jansson >= 2.5" >&5
+printf %s "checking for jansson >= 2.5... " >&6; }
 
 if test -n "$JANSSON_CFLAGS"; then
     pkg_cv_JANSSON_CFLAGS="$JANSSON_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jansson >= 2.5\""; } >&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jansson >= 2.5\""; } >&5
   ($PKG_CONFIG --exists --print-errors "jansson >= 2.5") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_JANSSON_CFLAGS=`$PKG_CONFIG --cflags "jansson >= 2.5" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
@@ -19703,10 +21888,10 @@ if test -n "$JANSSON_LIBS"; then
     pkg_cv_JANSSON_LIBS="$JANSSON_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jansson >= 2.5\""; } >&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jansson >= 2.5\""; } >&5
   ($PKG_CONFIG --exists --print-errors "jansson >= 2.5") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_JANSSON_LIBS=`$PKG_CONFIG --libs "jansson >= 2.5" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
@@ -19720,8 +21905,8 @@ fi
 
 
 if test $pkg_failed = yes; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
 
        have_jansson=no
 elif test $pkg_failed = untried; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
        have_jansson=no
 else
        JANSSON_CFLAGS=$pkg_cv_JANSSON_CFLAGS
        JANSSON_LIBS=$pkg_cv_JANSSON_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
        have_jansson=yes
 fi
-if test "x${have_jansson}" = "xyes"; then
+  if test "x${have_jansson}" = "xyes"; then
 
-$as_echo "#define HAVE_JANSSON 1" >>confdefs.h
+printf "%s\n" "#define HAVE_JANSSON 1" >>confdefs.h
 
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: $JANSSON_PKG_ERRORS" >&5
-$as_echo "$as_me: $JANSSON_PKG_ERRORS" >&6;}
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $JANSSON_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $JANSSON_PKG_ERRORS" >&6;}
+  fi
 fi
 
+if test "x${request_jansson}" = "xyes" &&
+   test "x${have_jansson}" != "xyes"; then
+  as_fn_error $? "jansson was requested (--with-jansson) but not found" "$LINENO" 5
+fi
 
 #  libsystemd (for src/nghttpx)
 have_libsystemd=no
 if test "x${request_systemd}" != "xno"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
-$as_echo_n "checking for SYSTEMD... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libsystemd >= 209" >&5
+printf %s "checking for libsystemd >= 209... " >&6; }
 
 if test -n "$SYSTEMD_CFLAGS"; then
     pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd >= 209\""; } >&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd >= 209\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libsystemd >= 209") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_SYSTEMD_CFLAGS=`$PKG_CONFIG --cflags "libsystemd >= 209" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
@@ -19787,10 +21977,10 @@ if test -n "$SYSTEMD_LIBS"; then
     pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd >= 209\""; } >&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd >= 209\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libsystemd >= 209") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_SYSTEMD_LIBS=`$PKG_CONFIG --libs "libsystemd >= 209" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
@@ -19804,8 +21994,8 @@ fi
 
 
 if test $pkg_failed = yes; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
 
        have_libsystemd=no
 elif test $pkg_failed = untried; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
        have_libsystemd=no
 else
        SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
        SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
        have_libsystemd=yes
 fi
   if test "x${have_libsystemd}" = "xyes"; then
 
-$as_echo "#define HAVE_LIBSYSTEMD 1" >>confdefs.h
+printf "%s\n" "#define HAVE_LIBSYSTEMD 1" >>confdefs.h
 
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: $SYSTEMD_PKG_ERRORS" >&5
-$as_echo "$as_me: $SYSTEMD_PKG_ERRORS" >&6;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $SYSTEMD_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $SYSTEMD_PKG_ERRORS" >&6;}
   fi
 fi
 
@@ -19848,19 +22038,21 @@ if test "x${request_systemd}" = "xyes" &&
 fi
 
 # libxml2 (for src/nghttp)
+have_libxml2=no
+if test "x${request_libxml2}" != "xno"; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBXML2" >&5
-$as_echo_n "checking for LIBXML2... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libxml-2.0 >= 2.6.26" >&5
+printf %s "checking for libxml-2.0 >= 2.6.26... " >&6; }
 
 if test -n "$LIBXML2_CFLAGS"; then
     pkg_cv_LIBXML2_CFLAGS="$LIBXML2_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0 >= 2.6.26\""; } >&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0 >= 2.6.26\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libxml-2.0 >= 2.6.26") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_LIBXML2_CFLAGS=`$PKG_CONFIG --cflags "libxml-2.0 >= 2.6.26" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
@@ -19874,10 +22066,10 @@ if test -n "$LIBXML2_LIBS"; then
     pkg_cv_LIBXML2_LIBS="$LIBXML2_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0 >= 2.6.26\""; } >&5
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0 >= 2.6.26\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libxml-2.0 >= 2.6.26") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_LIBXML2_LIBS=`$PKG_CONFIG --libs "libxml-2.0 >= 2.6.26" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
@@ -19891,8 +22083,8 @@ fi
 
 
 if test $pkg_failed = yes; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
 
        have_libxml2=no
 elif test $pkg_failed = untried; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
        have_libxml2=no
 else
        LIBXML2_CFLAGS=$pkg_cv_LIBXML2_CFLAGS
        LIBXML2_LIBS=$pkg_cv_LIBXML2_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
        have_libxml2=yes
 fi
-if test "x${have_libxml2}" = "xyes"; then
+  if test "x${have_libxml2}" = "xyes"; then
 
-$as_echo "#define HAVE_LIBXML2 1" >>confdefs.h
+printf "%s\n" "#define HAVE_LIBXML2 1" >>confdefs.h
 
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: $LIBXML2_PKG_ERRORS" >&5
-$as_echo "$as_me: $LIBXML2_PKG_ERRORS" >&6;}
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $LIBXML2_PKG_ERRORS" >&5
+printf "%s\n" "$as_me: $LIBXML2_PKG_ERRORS" >&6;}
+  fi
 fi
 
 if test "x${request_libxml2}" = "xyes" &&
 # jemalloc
 have_jemalloc=no
 if test "x${request_jemalloc}" != "xno"; then
-  save_LIBS=$LIBS
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing malloc_stats_print" >&5
-$as_echo_n "checking for library containing malloc_stats_print... " >&6; }
-if ${ac_cv_search_malloc_stats_print+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  if test "x${JEMALLOC_LIBS}" = "x" && test "x${JEMALLOC_CFLAGS}" = "x"; then
+    save_LIBS=$LIBS
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing malloc_stats_print" >&5
+printf %s "checking for library containing malloc_stats_print... " >&6; }
+if test ${ac_cv_search_malloc_stats_print+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -19958,60 +22153,63 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char malloc_stats_print ();
 int
-main ()
+main (void)
 {
 return malloc_stats_print ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' jemalloc; do
+for ac_lib in '' jemalloc
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib $PTHREAD_LDFLAGS $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_malloc_stats_print=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_malloc_stats_print+:} false; then :
+  if test ${ac_cv_search_malloc_stats_print+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_malloc_stats_print+:} false; then :
+if test ${ac_cv_search_malloc_stats_print+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_malloc_stats_print=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_malloc_stats_print" >&5
-$as_echo "$ac_cv_search_malloc_stats_print" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_malloc_stats_print" >&5
+printf "%s\n" "$ac_cv_search_malloc_stats_print" >&6; }
 ac_res=$ac_cv_search_malloc_stats_print
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
   have_jemalloc=yes
 fi
 
 
-  if test "x${have_jemalloc}" = "xyes"; then
-    jemalloc_libs=${ac_cv_search_malloc_stats_print}
-  else
-    # On Darwin, malloc_stats_print is je_malloc_stats_print
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing je_malloc_stats_print" >&5
-$as_echo_n "checking for library containing je_malloc_stats_print... " >&6; }
-if ${ac_cv_search_je_malloc_stats_print+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    if test "x${have_jemalloc}" = "xyes"; then
+      jemalloc_libs=${ac_cv_search_malloc_stats_print}
+    else
+      # On Darwin, malloc_stats_print is je_malloc_stats_print
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing je_malloc_stats_print" >&5
+printf %s "checking for library containing je_malloc_stats_print... " >&6; }
+if test ${ac_cv_search_je_malloc_stats_print+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -20019,62 +22217,66 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char je_malloc_stats_print ();
 int
-main ()
+main (void)
 {
 return je_malloc_stats_print ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' jemalloc; do
+for ac_lib in '' jemalloc
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib $PTHREAD_LDFLAGS $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_je_malloc_stats_print=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_je_malloc_stats_print+:} false; then :
+  if test ${ac_cv_search_je_malloc_stats_print+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_je_malloc_stats_print+:} false; then :
+if test ${ac_cv_search_je_malloc_stats_print+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_je_malloc_stats_print=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_je_malloc_stats_print" >&5
-$as_echo "$ac_cv_search_je_malloc_stats_print" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_je_malloc_stats_print" >&5
+printf "%s\n" "$ac_cv_search_je_malloc_stats_print" >&6; }
 ac_res=$ac_cv_search_je_malloc_stats_print
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
   have_jemalloc=yes
 fi
 
 
-    if test "x${have_jemalloc}" = "xyes"; then
-      jemalloc_libs=${ac_cv_search_je_malloc_stats_print}
+      if test "x${have_jemalloc}" = "xyes"; then
+        jemalloc_libs=${ac_cv_search_je_malloc_stats_print}
+      fi
     fi
-  fi
-
-  LIBS=$save_LIBS
 
-  if test "x${have_jemalloc}" = "xyes" &&
-     test "x${jemalloc_libs}" != "xnone required"; then
-    JEMALLOC_LIBS=${jemalloc_libs}
+    LIBS=$save_LIBS
 
+    if test "x${have_jemalloc}" = "xyes" &&
+       test "x${jemalloc_libs}" != "xnone required"; then
+      JEMALLOC_LIBS=${jemalloc_libs}
+    fi
+  else
+    have_jemalloc=yes
   fi
 fi
 
@@ -20090,7 +22292,8 @@ if test "x${request_asio_lib}" = "xyes"; then
 
 
 # Check whether --with-boost was given.
-if test "${with_boost+set}" = set; then :
+if test ${with_boost+y}
+then :
   withval=$with_boost;
     if test "$withval" = "no"; then
         want_boost="no"
@@ -20102,7 +22305,7 @@ if test "${with_boost+set}" = set; then :
         ac_boost_path="$withval"
     fi
 
-else
+else $as_nop
   want_boost="yes"
 fi
 
@@ -20110,7 +22313,8 @@ fi
 
 
 # Check whether --with-boost-libdir was given.
-if test "${with_boost_libdir+set}" = set; then :
+if test ${with_boost_libdir+y}
+then :
   withval=$with_boost_libdir;
         if test -d "$withval"
         then
@@ -20119,7 +22323,7 @@ if test "${with_boost_libdir+set}" = set; then :
                 as_fn_error $? "--with-boost-libdir expected directory name" "$LINENO" 5
         fi
 
-else
+else $as_nop
   ac_boost_lib_path=""
 
 fi
@@ -20135,8 +22339,8 @@ if test "x$want_boost" = "xyes"; then
         boost_lib_version_req_sub_minor="0"
         fi
     WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+  $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for boostlib >= $boost_lib_version_req" >&5
-$as_echo_n "checking for boostlib >= $boost_lib_version_req... " >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for boostlib >= $boost_lib_version_req" >&5
+printf %s "checking for boostlib >= $boost_lib_version_req... " >&6; }
     succeeded=no
 
                         libsubdirs="lib"
@@ -20205,7 +22409,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
     #include <boost/version.hpp>
 
 int
-main ()
+main (void)
 {
 
     #if BOOST_VERSION >= $WANT_BOOST_VERSION
@@ -20218,15 +22422,16 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
     succeeded=yes
     found_system=yes
 
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
     ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -20285,8 +22490,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
                         stage_version_shorten=`expr $stage_version : '\([0-9]*\.[0-9]*\)'`
                     V_CHECK=`expr $stage_version_shorten \>\= $_version`
                     if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
-                        { $as_echo "$as_me:${as_lineno-$LINENO}: We will use a staged boost library from $BOOST_ROOT" >&5
-$as_echo "$as_me: We will use a staged boost library from $BOOST_ROOT" >&6;}
+                        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: We will use a staged boost library from $BOOST_ROOT" >&5
+printf "%s\n" "$as_me: We will use a staged boost library from $BOOST_ROOT" >&6;}
                         BOOST_CPPFLAGS="-I$BOOST_ROOT"
                         BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir"
                     fi
@@ -20311,7 +22516,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
         #include <boost/version.hpp>
 
 int
-main ()
+main (void)
 {
 
         #if BOOST_VERSION >= $WANT_BOOST_VERSION
@@ -20324,15 +22529,16 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
 
-            { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
         succeeded=yes
         found_system=yes
 
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
         ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -20343,11 +22549,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
     if test "$succeeded" != "yes" ; then
         if test "$_version" = "0" ; then
-            { $as_echo "$as_me:${as_lineno-$LINENO}: We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option.  If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation." >&5
-$as_echo "$as_me: We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option.  If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation." >&6;}
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option.  If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation." >&5
+printf "%s\n" "$as_me: We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option.  If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation." >&6;}
         else
-            { $as_echo "$as_me:${as_lineno-$LINENO}: Your boost libraries seems to old (version $_version)." >&5
-$as_echo "$as_me: Your boost libraries seems to old (version $_version)." >&6;}
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Your boost libraries seems to old (version $_version)." >&5
+printf "%s\n" "$as_me: Your boost libraries seems to old (version $_version)." >&6;}
         fi
         # execute ACTION-IF-NOT-FOUND (if present):
         have_boost_base=no
@@ -20355,7 +22561,7 @@ $as_echo "$as_me: Your boost libraries seems to old (version $_version)." >&6;}
 
 
 
-$as_echo "#define HAVE_BOOST /**/" >>confdefs.h
+printf "%s\n" "#define HAVE_BOOST /**/" >>confdefs.h
 
         # execute ACTION-IF-FOUND (if present):
         have_boost_base=yes
@@ -20371,7 +22577,8 @@ fi
 
 
 # Check whether --with-boost-asio was given.
-if test "${with_boost_asio+set}" = set; then :
+if test ${with_boost_asio+y}
+then :
   withval=$with_boost_asio;
         if test "$withval" = "no"; then
                        want_boost="no"
@@ -20383,7 +22590,7 @@ if test "${with_boost_asio+set}" = set; then :
                ax_boost_user_asio_lib="$withval"
                fi
 
-else
+else $as_nop
   want_boost="yes"
 
 fi
                LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
                export LDFLAGS
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the Boost::ASIO library is available" >&5
-$as_echo_n "checking whether the Boost::ASIO library is available... " >&6; }
-if ${ax_cv_boost_asio+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the Boost::ASIO library is available" >&5
+printf %s "checking whether the Boost::ASIO library is available... " >&6; }
+if test ${ax_cv_boost_asio+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -20415,7 +22623,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
  #include <boost/asio.hpp>
 
 int
-main ()
+main (void)
 {
 
 
@@ -20430,12 +22638,13 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ax_cv_boost_asio=yes
-else
+else $as_nop
   ax_cv_boost_asio=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
          ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -20444,22 +22653,23 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_boost_asio" >&5
-$as_echo "$ax_cv_boost_asio" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_boost_asio" >&5
+printf "%s\n" "$ax_cv_boost_asio" >&6; }
                if test "x$ax_cv_boost_asio" = "xyes"; then
 
-$as_echo "#define HAVE_BOOST_ASIO /**/" >>confdefs.h
+printf "%s\n" "#define HAVE_BOOST_ASIO /**/" >>confdefs.h
 
                        BN=boost_system
                        BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/[^\/]*//'`
             if test "x$ax_boost_user_asio_lib" = "x"; then
                                for ax_lib in `ls $BOOSTLIBDIR/libboost_system*.so* $BOOSTLIBDIR/libboost_system*.dylib* $BOOSTLIBDIR/libboost_system*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_system.*\)\.so.*$;\1;' -e 's;^lib\(boost_system.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_system.*\)\.a.*$;\1;' ` ; do
-                                   as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_main" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -l$ax_lib" >&5
-$as_echo_n "checking for main in -l$ax_lib... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+                                   as_ac_Lib=`printf "%s\n" "ac_cv_lib_$ax_lib""_main" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -l$ax_lib" >&5
+printf %s "checking for main in -l$ax_lib... " >&6; }
+if eval test \${$as_ac_Lib+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-l$ax_lib  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -20467,40 +22677,43 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 
 int
-main ()
+main (void)
 {
 return main ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$as_ac_Lib=yes"
-else
+else $as_nop
   eval "$as_ac_Lib=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
 eval ac_res=\$$as_ac_Lib
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"
+then :
   BOOST_ASIO_LIB="-l$ax_lib"  link_thread="yes" break
-else
+else $as_nop
   link_thread="no"
 fi
 
                                done
             else
                for ax_lib in $ax_boost_user_asio_lib $BN-$ax_boost_user_asio_lib; do
-                                     as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_main" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -l$ax_lib" >&5
-$as_echo_n "checking for main in -l$ax_lib... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+                                     as_ac_Lib=`printf "%s\n" "ac_cv_lib_$ax_lib""_main" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -l$ax_lib" >&5
+printf %s "checking for main in -l$ax_lib... " >&6; }
+if eval test \${$as_ac_Lib+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-l$ax_lib  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -20508,28 +22721,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 
 int
-main ()
+main (void)
 {
 return main ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$as_ac_Lib=yes"
-else
+else $as_nop
   eval "$as_ac_Lib=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
 eval ac_res=\$$as_ac_Lib
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"
+then :
   BOOST_ASIO_LIB="-l$ax_lib"  link_asio="yes" break
-else
+else $as_nop
   link_asio="no"
 fi
 
@@ -20551,7 +22766,8 @@ fi
 
 
 # Check whether --with-boost-system was given.
-if test "${with_boost_system+set}" = set; then :
+if test ${with_boost_system+y}
+then :
   withval=$with_boost_system;
         if test "$withval" = "no"; then
                        want_boost="no"
@@ -20563,7 +22779,7 @@ if test "${with_boost_system+set}" = set; then :
                ax_boost_user_system_lib="$withval"
                fi
 
-else
+else $as_nop
   want_boost="yes"
 
 fi
                LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
                export LDFLAGS
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the Boost::System library is available" >&5
-$as_echo_n "checking whether the Boost::System library is available... " >&6; }
-if ${ax_cv_boost_system+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the Boost::System library is available" >&5
+printf %s "checking whether the Boost::System library is available... " >&6; }
+if test ${ax_cv_boost_system+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -20597,19 +22814,20 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 /* end confdefs.h.  */
 #include <boost/system/error_code.hpp>
 int
-main ()
+main (void)
 {
 boost::system::system_category
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ax_cv_boost_system=yes
-else
+else $as_nop
   ax_cv_boost_system=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
                         CXXFLAGS=$CXXFLAGS_SAVE
              ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -20619,13 +22837,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_boost_system" >&5
-$as_echo "$ax_cv_boost_system" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_boost_system" >&5
+printf "%s\n" "$ax_cv_boost_system" >&6; }
                if test "x$ax_cv_boost_system" = "xyes"; then
 
 
 
-$as_echo "#define HAVE_BOOST_SYSTEM /**/" >>confdefs.h
+printf "%s\n" "#define HAVE_BOOST_SYSTEM /**/" >>confdefs.h
 
             BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/[^\/]*//'`
 
@@ -20633,12 +22851,13 @@ $as_echo "#define HAVE_BOOST_SYSTEM /**/" >>confdefs.h
             if test "x$ax_boost_user_system_lib" = "x"; then
                 for libextension in `ls -r $BOOSTLIBDIR/libboost_system* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do
                      ax_lib=${libextension}
-                                   as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
-$as_echo_n "checking for exit in -l$ax_lib... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+                                   as_ac_Lib=`printf "%s\n" "ac_cv_lib_$ax_lib""_exit" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
+printf %s "checking for exit in -l$ax_lib... " >&6; }
+if eval test \${$as_ac_Lib+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-l$ax_lib  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -20647,33 +22866,32 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char exit ();
 int
-main ()
+main (void)
 {
 return exit ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$as_ac_Lib=yes"
-else
+else $as_nop
   eval "$as_ac_Lib=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
 eval ac_res=\$$as_ac_Lib
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"
+then :
   BOOST_SYSTEM_LIB="-l$ax_lib";  link_system="yes"; break
-else
+else $as_nop
   link_system="no"
 fi
 
                 if test "x$link_system" != "xyes"; then
                 for libextension in `ls -r $BOOSTLIBDIR/boost_system* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do
                      ax_lib=${libextension}
-                                   as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
-$as_echo_n "checking for exit in -l$ax_lib... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+                                   as_ac_Lib=`printf "%s\n" "ac_cv_lib_$ax_lib""_exit" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
+printf %s "checking for exit in -l$ax_lib... " >&6; }
+if eval test \${$as_ac_Lib+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-l$ax_lib  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -20695,33 +22914,32 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char exit ();
 int
-main ()
+main (void)
 {
 return exit ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$as_ac_Lib=yes"
-else
+else $as_nop
   eval "$as_ac_Lib=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
 eval ac_res=\$$as_ac_Lib
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"
+then :
   BOOST_SYSTEM_LIB="-l$ax_lib";  link_system="yes"; break
-else
+else $as_nop
   link_system="no"
 fi
 
 
             else
                for ax_lib in $ax_boost_user_system_lib boost_system-$ax_boost_user_system_lib; do
-                                     as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
-$as_echo_n "checking for exit in -l$ax_lib... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+                                     as_ac_Lib=`printf "%s\n" "ac_cv_lib_$ax_lib""_exit" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
+printf %s "checking for exit in -l$ax_lib... " >&6; }
+if eval test \${$as_ac_Lib+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-l$ax_lib  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -20744,33 +22963,32 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char exit ();
 int
-main ()
+main (void)
 {
 return exit ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$as_ac_Lib=yes"
-else
+else $as_nop
   eval "$as_ac_Lib=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
 eval ac_res=\$$as_ac_Lib
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"
+then :
   BOOST_SYSTEM_LIB="-l$ax_lib";  link_system="yes"; break
-else
+else $as_nop
   link_system="no"
 fi
 
@@ -20792,7 +23010,8 @@ fi
 
 
 # Check whether --with-boost-thread was given.
-if test "${with_boost_thread+set}" = set; then :
+if test ${with_boost_thread+y}
+then :
   withval=$with_boost_thread;
         if test "$withval" = "no"; then
                        want_boost="no"
@@ -20804,7 +23023,7 @@ if test "${with_boost_thread+set}" = set; then :
                ax_boost_user_thread_lib="$withval"
                fi
 
-else
+else $as_nop
   want_boost="yes"
 
 fi
                LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
                export LDFLAGS
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the Boost::Thread library is available" >&5
-$as_echo_n "checking whether the Boost::Thread library is available... " >&6; }
-if ${ax_cv_boost_thread+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the Boost::Thread library is available" >&5
+printf %s "checking whether the Boost::Thread library is available... " >&6; }
+if test ${ax_cv_boost_thread+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -20845,7 +23065,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 /* end confdefs.h.  */
 #include <boost/thread/thread.hpp>
 int
-main ()
+main (void)
 {
 boost::thread_group thrds;
                                    return 0;
@@ -20853,12 +23073,13 @@ boost::thread_group thrds;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ax_cv_boost_thread=yes
-else
+else $as_nop
   ax_cv_boost_thread=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
                         CXXFLAGS=$CXXFLAGS_SAVE
              ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -20868,8 +23089,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_boost_thread" >&5
-$as_echo "$ax_cv_boost_thread" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_boost_thread" >&5
+printf "%s\n" "$ax_cv_boost_thread" >&6; }
                if test "x$ax_cv_boost_thread" = "xyes"; then
            if test "x$host_os" = "xsolaris" ; then
                          BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS"
@@ -20882,7 +23103,7 @@ $as_echo "$ax_cv_boost_thread" >&6; }
 
 
 
-$as_echo "#define HAVE_BOOST_THREAD /**/" >>confdefs.h
+printf "%s\n" "#define HAVE_BOOST_THREAD /**/" >>confdefs.h
 
             BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/[^\/]*//'`
 
@@ -20896,12 +23117,13 @@ $as_echo "#define HAVE_BOOST_THREAD /**/" >>confdefs.h
             if test "x$ax_boost_user_thread_lib" = "x"; then
                 for libextension in `ls -r $BOOSTLIBDIR/libboost_thread* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'`; do
                      ax_lib=${libextension}
-                                   as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
-$as_echo_n "checking for exit in -l$ax_lib... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+                                   as_ac_Lib=`printf "%s\n" "ac_cv_lib_$ax_lib""_exit" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
+printf %s "checking for exit in -l$ax_lib... " >&6; }
+if eval test \${$as_ac_Lib+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-l$ax_lib  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -20910,33 +23132,32 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char exit ();
 int
-main ()
+main (void)
 {
 return exit ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$as_ac_Lib=yes"
-else
+else $as_nop
   eval "$as_ac_Lib=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
 eval ac_res=\$$as_ac_Lib
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"
+then :
   BOOST_THREAD_LIB="-l$ax_lib";  link_thread="yes"; break
-else
+else $as_nop
   link_thread="no"
 fi
 
                 if test "x$link_thread" != "xyes"; then
                 for libextension in `ls -r $BOOSTLIBDIR/boost_thread* 2>/dev/null | sed 's,.*/,,' | sed 's,\..*,,'`; do
                      ax_lib=${libextension}
-                                   as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
-$as_echo_n "checking for exit in -l$ax_lib... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+                                   as_ac_Lib=`printf "%s\n" "ac_cv_lib_$ax_lib""_exit" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
+printf %s "checking for exit in -l$ax_lib... " >&6; }
+if eval test \${$as_ac_Lib+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-l$ax_lib  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -20958,33 +23180,32 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char exit ();
 int
-main ()
+main (void)
 {
 return exit ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$as_ac_Lib=yes"
-else
+else $as_nop
   eval "$as_ac_Lib=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
 eval ac_res=\$$as_ac_Lib
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"
+then :
   BOOST_THREAD_LIB="-l$ax_lib";  link_thread="yes"; break
-else
+else $as_nop
   link_thread="no"
 fi
 
 
             else
                for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do
-                                     as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
-$as_echo_n "checking for exit in -l$ax_lib... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+                                     as_ac_Lib=`printf "%s\n" "ac_cv_lib_$ax_lib""_exit" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5
+printf %s "checking for exit in -l$ax_lib... " >&6; }
+if eval test \${$as_ac_Lib+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-l$ax_lib  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -21007,33 +23229,32 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char exit ();
 int
-main ()
+main (void)
 {
 return exit ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$as_ac_Lib=yes"
-else
+else $as_nop
   eval "$as_ac_Lib=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
 eval ac_res=\$$as_ac_Lib
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"
+then :
   BOOST_THREAD_LIB="-l$ax_lib";  link_thread="yes"; break
-else
+else $as_nop
   link_thread="no"
 fi
 
@@ -21094,6 +23315,35 @@ else
 fi
 
 
+# Check HTTP/3 support
+enable_http3=no
+if test "x${request_http3}" != "xno" &&
+   (test "x${have_ssl_is_quic}" = "xyes" ||
+    test "x${have_boringssl_quic}" = "xyes") &&
+   test "x${have_libngtcp2}" = "xyes" &&
+   (test "x${have_libngtcp2_crypto_openssl}" = "xyes" ||
+    test "x${have_libngtcp2_crypto_boringssl}" = "xyes") &&
+   test "x${have_libnghttp3}" = "xyes"; then
+  enable_http3=yes
+
+printf "%s\n" "#define ENABLE_HTTP3 1" >>confdefs.h
+
+fi
+
+if test "x${request_http3}" = "xyes" &&
+   test "x${enable_http3}" != "xyes"; then
+  as_fn_error $? "HTTP/3 was requested (--enable-http3) but dependencies are not met." "$LINENO" 5
+fi
+
+ if  test "x${enable_http3}" = "xyes" ; then
+  ENABLE_HTTP3_TRUE=
+  ENABLE_HTTP3_FALSE='#'
+else
+  ENABLE_HTTP3_TRUE='#'
+  ENABLE_HTTP3_FALSE=
+fi
+
+
 enable_hpack_tools=no
 # HPACK tools requires jansson
 if test "x${request_hpack_tools}" != "xno" &&
@@ -21170,7 +23420,7 @@ if test "x${enable_examples}" = "xyes" ||
     # We are going to build mruby
     have_mruby=yes
 
-$as_echo "#define HAVE_MRUBY 1" >>confdefs.h
+printf "%s\n" "#define HAVE_MRUBY 1" >>confdefs.h
 
     LIBMRUBY_LIBS="-lmruby -lm"
     LIBMRUBY_CFLAGS=
@@ -21182,7 +23432,7 @@ $as_echo "#define HAVE_MRUBY 1" >>confdefs.h
   if test "x${request_neverbleed}" = "xyes"; then
     have_neverbleed=yes
 
-$as_echo "#define HAVE_NEVERBLEED 1" >>confdefs.h
+printf "%s\n" "#define HAVE_NEVERBLEED 1" >>confdefs.h
 
   fi
 fi
@@ -21217,7 +23467,7 @@ enable_python_bindings=no
 if test "x${request_python_bindings}" != "xno" &&
    test "x${CYTHON}" != "x" &&
    test "x${PYTHON}" != "x:" &&
-   test "x${have_python_dev}" = "xyes"; then
+   test "x${PYTHON_VERSION}" != "x"; then
   enable_python_bindings=yes
 fi
 
 
 # Checks for header files.
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable assertions" >&5
-$as_echo_n "checking whether to enable assertions... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable assertions" >&5
+printf %s "checking whether to enable assertions... " >&6; }
   # Check whether --enable-assert was given.
-if test "${enable_assert+set}" = set; then :
+if test ${enable_assert+y}
+then :
   enableval=$enable_assert; ac_enable_assert=$enableval
-     if       test "x$enableval" = xno; then :
+     if       test "x$enableval" = xno
+then :
 
-$as_echo "#define NDEBUG 1" >>confdefs.h
+printf "%s\n" "#define NDEBUG 1" >>confdefs.h
 
-elif test "x$enableval" != xyes; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: invalid argument supplied to --enable-assert" >&5
-$as_echo "$as_me: WARNING: invalid argument supplied to --enable-assert" >&2;}
+elif test "x$enableval" != xyes
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: invalid argument supplied to --enable-assert" >&5
+printf "%s\n" "$as_me: WARNING: invalid argument supplied to --enable-assert" >&2;}
        ac_enable_assert=yes
 fi
-else
+else $as_nop
   ac_enable_assert=yes
 fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_enable_assert" >&5
-$as_echo "$ac_enable_assert" >&6; }
-
-for ac_header in  \
-  arpa/inet.h \
-  fcntl.h \
-  inttypes.h \
-  limits.h \
-  netdb.h \
-  netinet/in.h \
-  pwd.h \
-  stddef.h \
-  stdint.h \
-  stdlib.h \
-  string.h \
-  sys/socket.h \
-  sys/time.h \
-  syslog.h \
-  time.h \
-  unistd.h \
-
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_enable_assert" >&5
+printf "%s\n" "$ac_enable_assert" >&6; }
+
+ac_fn_c_check_header_compile "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default"
+if test "x$ac_cv_header_arpa_inet_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_ARPA_INET_H 1" >>confdefs.h
 
 fi
+ac_fn_c_check_header_compile "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default"
+if test "x$ac_cv_header_fcntl_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_FCNTL_H 1" >>confdefs.h
 
-done
+fi
+ac_fn_c_check_header_compile "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default"
+if test "x$ac_cv_header_inttypes_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_INTTYPES_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIMITS_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "netdb.h" "ac_cv_header_netdb_h" "$ac_includes_default"
+if test "x$ac_cv_header_netdb_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_NETDB_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "$ac_includes_default"
+if test "x$ac_cv_header_netinet_in_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_NETINET_IN_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "pwd.h" "ac_cv_header_pwd_h" "$ac_includes_default"
+if test "x$ac_cv_header_pwd_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_PWD_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default"
+if test "x$ac_cv_header_stddef_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_STDDEF_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdint_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_STDINT_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_STDLIB_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRING_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_socket_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_SOCKET_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_time_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "syslog.h" "ac_cv_header_syslog_h" "$ac_includes_default"
+if test "x$ac_cv_header_syslog_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYSLOG_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_time_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_TIME_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_UNISTD_H 1" >>confdefs.h
+
+fi
 
 
 # Checks for typedefs, structures, and compiler characteristics.
 ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = xyes; then :
+if test "x$ac_cv_type_size_t" = xyes
+then :
 
-else
+else $as_nop
 
-cat >>confdefs.h <<_ACEOF
-#define size_t unsigned int
-_ACEOF
+printf "%s\n" "#define size_t unsigned int" >>confdefs.h
 
 fi
 
 ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
-if test "x$ac_cv_type_ssize_t" = xyes; then :
+if test "x$ac_cv_type_ssize_t" = xyes
+then :
 
-else
+else $as_nop
 
-cat >>confdefs.h <<_ACEOF
-#define ssize_t int
-_ACEOF
+printf "%s\n" "#define ssize_t int" >>confdefs.h
 
 fi
 
@@ -21343,12 +23661,10 @@ case $ac_cv_c_uint8_t in #(
   no|yes) ;; #(
   *)
 
-$as_echo "#define _UINT8_T 1" >>confdefs.h
+printf "%s\n" "#define _UINT8_T 1" >>confdefs.h
 
 
-cat >>confdefs.h <<_ACEOF
-#define uint8_t $ac_cv_c_uint8_t
-_ACEOF
+printf "%s\n" "#define uint8_t $ac_cv_c_uint8_t" >>confdefs.h
 ;;
   esac
 
@@ -21358,9 +23674,7 @@ case $ac_cv_c_uint16_t in #(
   *)
 
 
-cat >>confdefs.h <<_ACEOF
-#define uint16_t $ac_cv_c_uint16_t
-_ACEOF
+printf "%s\n" "#define uint16_t $ac_cv_c_uint16_t" >>confdefs.h
 ;;
   esac
 
@@ -21369,12 +23683,10 @@ case $ac_cv_c_uint32_t in #(
   no|yes) ;; #(
   *)
 
-$as_echo "#define _UINT32_T 1" >>confdefs.h
+printf "%s\n" "#define _UINT32_T 1" >>confdefs.h
 
 
-cat >>confdefs.h <<_ACEOF
-#define uint32_t $ac_cv_c_uint32_t
-_ACEOF
+printf "%s\n" "#define uint32_t $ac_cv_c_uint32_t" >>confdefs.h
 ;;
   esac
 
@@ -21383,12 +23695,10 @@ case $ac_cv_c_uint64_t in #(
   no|yes) ;; #(
   *)
 
-$as_echo "#define _UINT64_T 1" >>confdefs.h
+printf "%s\n" "#define _UINT64_T 1" >>confdefs.h
 
 
-cat >>confdefs.h <<_ACEOF
-#define uint64_t $ac_cv_c_uint64_t
-_ACEOF
+printf "%s\n" "#define uint64_t $ac_cv_c_uint64_t" >>confdefs.h
 ;;
   esac
 
@@ -21397,9 +23707,7 @@ case $ac_cv_c_int8_t in #(
   no|yes) ;; #(
   *)
 
-cat >>confdefs.h <<_ACEOF
-#define int8_t $ac_cv_c_int8_t
-_ACEOF
+printf "%s\n" "#define int8_t $ac_cv_c_int8_t" >>confdefs.h
 ;;
 esac
 
@@ -21408,9 +23716,7 @@ case $ac_cv_c_int16_t in #(
   no|yes) ;; #(
   *)
 
-cat >>confdefs.h <<_ACEOF
-#define int16_t $ac_cv_c_int16_t
-_ACEOF
+printf "%s\n" "#define int16_t $ac_cv_c_int16_t" >>confdefs.h
 ;;
 esac
 
@@ -21419,9 +23725,7 @@ case $ac_cv_c_int32_t in #(
   no|yes) ;; #(
   *)
 
-cat >>confdefs.h <<_ACEOF
-#define int32_t $ac_cv_c_int32_t
-_ACEOF
+printf "%s\n" "#define int32_t $ac_cv_c_int32_t" >>confdefs.h
 ;;
 esac
 
@@ -21430,79 +23734,105 @@ case $ac_cv_c_int64_t in #(
   no|yes) ;; #(
   *)
 
-cat >>confdefs.h <<_ACEOF
-#define int64_t $ac_cv_c_int64_t
-_ACEOF
+printf "%s\n" "#define int64_t $ac_cv_c_int64_t" >>confdefs.h
 ;;
 esac
 
 ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
-if test "x$ac_cv_type_off_t" = xyes; then :
+if test "x$ac_cv_type_off_t" = xyes
+then :
 
-else
+else $as_nop
 
-cat >>confdefs.h <<_ACEOF
-#define off_t long int
-_ACEOF
+printf "%s\n" "#define off_t long int" >>confdefs.h
 
 fi
 
-ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = xyes; then :
 
-else
+  ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default
+"
+if test "x$ac_cv_type_pid_t" = xyes
+then :
+
+else $as_nop
+                                          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+          #if defined _WIN64 && !defined __CYGWIN__
+          LLP64
+          #endif
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
 
-cat >>confdefs.h <<_ACEOF
-#define pid_t int
 _ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_pid_type='int'
+else $as_nop
+  ac_pid_type='__int64'
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+
+printf "%s\n" "#define pid_t $ac_pid_type" >>confdefs.h
+
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
-$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
-if ${ac_cv_type_uid_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
+printf %s "checking for uid_t in sys/types.h... " >&6; }
+if test ${ac_cv_type_uid_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <sys/types.h>
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "uid_t" >/dev/null 2>&1; then :
+  $EGREP "uid_t" >/dev/null 2>&1
+then :
   ac_cv_type_uid_t=yes
-else
+else $as_nop
   ac_cv_type_uid_t=no
 fi
-rm -f conftest*
+rm -rf conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
-$as_echo "$ac_cv_type_uid_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
+printf "%s\n" "$ac_cv_type_uid_t" >&6; }
 if test $ac_cv_type_uid_t = no; then
 
-$as_echo "#define uid_t int" >>confdefs.h
+printf "%s\n" "#define uid_t int" >>confdefs.h
 
 
-$as_echo "#define gid_t int" >>confdefs.h
+printf "%s\n" "#define gid_t int" >>confdefs.h
 
 fi
 
 ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default"
-if test "x$ac_cv_type_ptrdiff_t" = xyes; then :
+if test "x$ac_cv_type_ptrdiff_t" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_PTRDIFF_T 1
-_ACEOF
+printf "%s\n" "#define HAVE_PTRDIFF_T 1" >>confdefs.h
 
 
 fi
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
-$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
-if ${ac_cv_c_bigendian+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+printf %s "checking whether byte ordering is bigendian... " >&6; }
+if test ${ac_cv_c_bigendian+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_cv_c_bigendian=unknown
     # See if we're dealing with a universal compiler.
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -21513,7 +23843,8 @@ else
             typedef int dummy;
 
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
 
        # Check for potential -arch flags.  It is not universal unless
        # there are at least two -arch flags with different values.
@@ -21537,7 +23868,7 @@ if ac_fn_c_try_compile "$LINENO"; then :
         fi
        done
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
     if test $ac_cv_c_bigendian = unknown; then
       # See if sys/param.h defines the BYTE_ORDER macro.
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -21546,7 +23877,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
             #include <sys/param.h>
 
 int
-main ()
+main (void)
 {
 #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
                     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
@@ -21558,7 +23889,8 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   # It does; now see whether it defined to BIG_ENDIAN or not.
         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -21566,7 +23898,7 @@ if ac_fn_c_try_compile "$LINENO"; then :
                #include <sys/param.h>
 
 int
-main ()
+main (void)
 {
 #if BYTE_ORDER != BIG_ENDIAN
                 not big endian
@@ -21576,14 +23908,15 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_c_bigendian=yes
-else
+else $as_nop
   ac_cv_c_bigendian=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
     fi
     if test $ac_cv_c_bigendian = unknown; then
       # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
@@ -21592,7 +23925,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 #include <limits.h>
 
 int
-main ()
+main (void)
 {
 #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
              bogus endian macros
@@ -21602,14 +23935,15 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   # It does; now see whether it defined to _BIG_ENDIAN or not.
         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <limits.h>
 
 int
-main ()
+main (void)
 {
 #ifndef _BIG_ENDIAN
                 not big endian
@@ -21619,31 +23953,33 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_c_bigendian=yes
-else
+else $as_nop
   ac_cv_c_bigendian=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
     fi
     if test $ac_cv_c_bigendian = unknown; then
       # Compile a test program.
-      if test "$cross_compiling" = yes; then :
+      if test "$cross_compiling" = yes
+then :
   # Try to guess by grepping values from an object file.
         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-short int ascii_mm[] =
+unsigned short int ascii_mm[] =
                  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
-               short int ascii_ii[] =
+               unsigned short int ascii_ii[] =
                  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
                int use_ascii (int i) {
                  return ascii_mm[i] + ascii_ii[i];
                }
-               short int ebcdic_ii[] =
+               unsigned short int ebcdic_ii[] =
                  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
-               short int ebcdic_mm[] =
+               unsigned short int ebcdic_mm[] =
                  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
                int use_ebcdic (int i) {
                  return ebcdic_mm[i] + ebcdic_ii[i];
@@ -21651,14 +23987,15 @@ short int ascii_mm[] =
                extern int foo;
 
 int
-main ()
+main (void)
 {
 return use_ascii (foo) == use_ebcdic (foo);
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
              ac_cv_c_bigendian=yes
            fi
@@ -21671,13 +24008,13 @@ if ac_fn_c_try_compile "$LINENO"; then :
              fi
            fi
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
 int
-main ()
+main (void)
 {
 
             /* Are we little or big endian?  From Harbison&Steele.  */
@@ -21693,9 +24030,10 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   ac_cv_c_bigendian=no
-else
+else $as_nop
   ac_cv_c_bigendian=yes
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 
     fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
-$as_echo "$ac_cv_c_bigendian" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+printf "%s\n" "$ac_cv_c_bigendian" >&6; }
  case $ac_cv_c_bigendian in #(
    yes)
-     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+     printf "%s\n" "#define WORDS_BIGENDIAN 1" >>confdefs.h
 ;; #(
    no)
       ;; #(
    universal)
 
-$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+printf "%s\n" "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
 
      ;; #(
    *)
@@ -21722,32 +24060,34 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
  presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
  esac
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
-$as_echo_n "checking for inline... " >&6; }
-if ${ac_cv_c_inline+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+printf %s "checking for inline... " >&6; }
+if test ${ac_cv_c_inline+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #ifndef __cplusplus
 typedef int foo_t;
-static $ac_kw foo_t static_foo () {return 0; }
-$ac_kw foo_t foo () {return 0; }
+static $ac_kw foo_t static_foo (void) {return 0; }
+$ac_kw foo_t foo (void) {return 0; }
 #endif
 
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_c_inline=$ac_kw
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   test "$ac_cv_c_inline" != no && break
 done
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
-$as_echo "$ac_cv_c_inline" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+printf "%s\n" "$ac_cv_c_inline" >&6; }
 
 case $ac_cv_c_inline in
   inline | yes) ;;
@@ -21765,17 +24105,19 @@ _ACEOF
 esac
 
 # Check whether --enable-largefile was given.
-if test "${enable_largefile+set}" = set; then :
+if test ${enable_largefile+y}
+then :
   enableval=$enable_largefile;
 fi
 
 if test "$enable_largefile" != no; then
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
-$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
-if ${ac_cv_sys_largefile_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+printf %s "checking for special C compiler options needed for large files... " >&6; }
+if test ${ac_cv_sys_largefile_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_cv_sys_largefile_CC=no
      if test "$GCC" != yes; then
        ac_save_CC=$CC
@@ -21789,44 +24131,47 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-        if ac_fn_c_try_compile "$LINENO"; then :
+        if ac_fn_c_try_compile "$LINENO"
+then :
   break
 fi
-rm -f core conftest.err conftest.$ac_objext
+rm -f core conftest.err conftest.$ac_objext conftest.beam
         CC="$CC -n32"
-        if ac_fn_c_try_compile "$LINENO"; then :
+        if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_sys_largefile_CC=' -n32'; break
 fi
-rm -f core conftest.err conftest.$ac_objext
+rm -f core conftest.err conftest.$ac_objext conftest.beam
         break
        done
        CC=$ac_save_CC
        rm -f conftest.$ac_ext
     fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
-$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+printf "%s\n" "$ac_cv_sys_largefile_CC" >&6; }
   if test "$ac_cv_sys_largefile_CC" != no; then
     CC=$CC$ac_cv_sys_largefile_CC
   fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
-if ${ac_cv_sys_file_offset_bits+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+printf %s "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if test ${ac_cv_sys_file_offset_bits+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   while :; do
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -21835,22 +24180,23 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_sys_file_offset_bits=no; break
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #define _FILE_OFFSET_BITS 64
@@ -21859,43 +24205,43 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_sys_file_offset_bits=64; break
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   ac_cv_sys_file_offset_bits=unknown
   break
 done
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
-$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+printf "%s\n" "$ac_cv_sys_file_offset_bits" >&6; }
 case $ac_cv_sys_file_offset_bits in #(
   no | unknown) ;;
   *)
-cat >>confdefs.h <<_ACEOF
-#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
-_ACEOF
+printf "%s\n" "#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits" >>confdefs.h
 ;;
 esac
 rm -rf conftest*
   if test $ac_cv_sys_file_offset_bits = unknown; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
-$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
-if ${ac_cv_sys_large_files+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+printf %s "checking for _LARGE_FILES value needed for large files... " >&6; }
+if test ${ac_cv_sys_large_files+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   while :; do
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -21904,22 +24250,23 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_sys_large_files=no; break
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #define _LARGE_FILES 1
@@ -21928,48 +24275,46 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_sys_large_files=1; break
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   ac_cv_sys_large_files=unknown
   break
 done
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
-$as_echo "$ac_cv_sys_large_files" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+printf "%s\n" "$ac_cv_sys_large_files" >&6; }
 case $ac_cv_sys_large_files in #(
   no | unknown) ;;
   *)
-cat >>confdefs.h <<_ACEOF
-#define _LARGE_FILES $ac_cv_sys_large_files
-_ACEOF
+printf "%s\n" "#define _LARGE_FILES $ac_cv_sys_large_files" >>confdefs.h
 ;;
 esac
 rm -rf conftest*
   fi
-
-
 fi
 
 
 ac_fn_c_check_member "$LINENO" "struct tm" "tm_gmtoff" "ac_cv_member_struct_tm_tm_gmtoff" "#include <time.h>
 "
-if test "x$ac_cv_member_struct_tm_tm_gmtoff" = xyes; then :
+if test "x$ac_cv_member_struct_tm_tm_gmtoff" = xyes
+then :
   have_struct_tm_tm_gmtoff=yes
-else
+else $as_nop
   have_struct_tm_tm_gmtoff=no
 fi
 
@@ -21980,9 +24325,10 @@ ac_fn_c_check_member "$LINENO" "struct sockaddr_in" "sin_len" "ac_cv_member_stru
 #include <netinet/in.h>
 
 "
-if test "x$ac_cv_member_struct_sockaddr_in_sin_len" = xyes; then :
+if test "x$ac_cv_member_struct_sockaddr_in_sin_len" = xyes
+then :
 
-$as_echo "#define HAVE_SOCKADDR_IN_SIN_LEN 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SOCKADDR_IN_SIN_LEN 1" >>confdefs.h
 
 fi
 
@@ -21993,16 +24339,17 @@ ac_fn_c_check_member "$LINENO" "struct sockaddr_in6" "sin6_len" "ac_cv_member_st
 #include <netinet/in.h>
 
 "
-if test "x$ac_cv_member_struct_sockaddr_in6_sin6_len" = xyes; then :
+if test "x$ac_cv_member_struct_sockaddr_in6_sin6_len" = xyes
+then :
 
-$as_echo "#define HAVE_SOCKADDR_IN6_SIN6_LEN 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SOCKADDR_IN6_SIN6_LEN 1" >>confdefs.h
 
 fi
 
 
 if test "x$have_struct_tm_tm_gmtoff" = "xyes"; then
 
-$as_echo "#define HAVE_STRUCT_TM_TM_GMTOFF 1" >>confdefs.h
+printf "%s\n" "#define HAVE_STRUCT_TM_TM_GMTOFF 1" >>confdefs.h
 
 fi
 
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5
-$as_echo_n "checking size of int *... " >&6; }
-if ${ac_cv_sizeof_int_p+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5
+printf %s "checking size of int *... " >&6; }
+if test ${ac_cv_sizeof_int_p+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_int_p" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (int *)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -22031,14 +24380,12 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int_p" >&5
-$as_echo "$ac_cv_sizeof_int_p" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int_p" >&5
+printf "%s\n" "$ac_cv_sizeof_int_p" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT_P $ac_cv_sizeof_int_p
-_ACEOF
+printf "%s\n" "#define SIZEOF_INT_P $ac_cv_sizeof_int_p" >>confdefs.h
 
 
 
@@ -22046,17 +24393,19 @@ _ACEOF
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
-$as_echo_n "checking size of time_t... " >&6; }
-if ${ac_cv_sizeof_time_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
+printf %s "checking size of time_t... " >&6; }
+if test ${ac_cv_sizeof_time_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_time_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (time_t)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -22065,14 +24414,12 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
-$as_echo "$ac_cv_sizeof_time_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
+printf "%s\n" "$ac_cv_sizeof_time_t" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
-_ACEOF
+printf "%s\n" "#define SIZEOF_TIME_T $ac_cv_sizeof_time_t" >>confdefs.h
 
 
 
@@ -22081,33 +24428,28 @@ _ACEOF
 # Don't check malloc, since it does not play nicely with C++ stdlib
 # AC_FUNC_MALLOC
 
-for ac_header in unistd.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
-if test "x$ac_cv_header_unistd_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_UNISTD_H 1
-_ACEOF
-
-fi
-
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working chown" >&5
-$as_echo_n "checking for working chown... " >&6; }
-if ${ac_cv_func_chown_works+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "$cross_compiling" = yes; then :
-  ac_cv_func_chown_works=no
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working chown" >&5
+printf %s "checking for working chown... " >&6; }
+if test ${ac_cv_func_chown_works+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "$cross_compiling" = yes
+then :
+  case "$host_os" in # ((
+                         # Guess yes on glibc systems.
+                 *-gnu*) ac_cv_func_chown_works=yes ;;
+                         # If we don't know, assume the worst.
+                 *)      ac_cv_func_chown_works=no ;;
+               esac
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
 #include <fcntl.h>
 
 int
-main ()
+main (void)
 {
   char *f = "conftest.chown";
   struct stat before, after;
@@ -22126,9 +24468,10 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   ac_cv_func_chown_works=yes
-else
+else $as_nop
   ac_cv_func_chown_works=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 rm -f conftest.chown
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_chown_works" >&5
-$as_echo "$ac_cv_func_chown_works" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_chown_works" >&5
+printf "%s\n" "$ac_cv_func_chown_works" >&6; }
 if test $ac_cv_func_chown_works = yes; then
 
-$as_echo "#define HAVE_CHOWN 1" >>confdefs.h
+printf "%s\n" "#define HAVE_CHOWN 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5
-$as_echo_n "checking for error_at_line... " >&6; }
-if ${ac_cv_lib_error_at_line+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5
+printf %s "checking for error_at_line... " >&6; }
+if test ${ac_cv_lib_error_at_line+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <error.h>
 int
-main ()
+main (void)
 {
 error_at_line (0, 0, "", 0, "an error occurred");
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_error_at_line=yes
-else
+else $as_nop
   ac_cv_lib_error_at_line=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5
-$as_echo "$ac_cv_lib_error_at_line" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5
+printf "%s\n" "$ac_cv_lib_error_at_line" >&6; }
 if test $ac_cv_lib_error_at_line = no; then
   case " $LIBOBJS " in
   *" error.$ac_objext "* ) ;;
@@ -22181,44 +24526,39 @@ esac
 
 fi
 
-for ac_header in vfork.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
-if test "x$ac_cv_header_vfork_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_VFORK_H 1
-_ACEOF
-
-fi
 
+ac_func=
+for ac_item in $ac_func_c_list
+do
+  if test $ac_func; then
+    ac_fn_c_check_func "$LINENO" $ac_func ac_cv_func_$ac_func
+    if eval test \"x\$ac_cv_func_$ac_func\" = xyes; then
+      echo "#define $ac_item 1" >> confdefs.h
+    fi
+    ac_func=
+  else
+    ac_func=$ac_item
+  fi
 done
 
-for ac_func in fork vfork
-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
 
-fi
-done
 
 if test "x$ac_cv_func_fork" = xyes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
-$as_echo_n "checking for working fork... " >&6; }
-if ${ac_cv_func_fork_works+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "$cross_compiling" = yes; then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
+printf %s "checking for working fork... " >&6; }
+if test ${ac_cv_func_fork_works+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "$cross_compiling" = yes
+then :
   ac_cv_func_fork_works=cross
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
 int
-main ()
+main (void)
 {
 
          /* By Ruediger Kuhlmann. */
@@ -22228,9 +24568,10 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   ac_cv_func_fork_works=yes
-else
+else $as_nop
   ac_cv_func_fork_works=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -22238,8 +24579,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
-$as_echo "$ac_cv_func_fork_works" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
+printf "%s\n" "$ac_cv_func_fork_works" >&6; }
 
 else
   ac_cv_func_fork_works=$ac_cv_func_fork
@@ -22254,27 +24595,37 @@ if test "x$ac_cv_func_fork_works" = xcross; then
       ac_cv_func_fork_works=yes
       ;;
   esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
-$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+printf "%s\n" "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
 fi
 ac_cv_func_vfork_works=$ac_cv_func_vfork
 if test "x$ac_cv_func_vfork" = xyes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
-$as_echo_n "checking for working vfork... " >&6; }
-if ${ac_cv_func_vfork_works+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "$cross_compiling" = yes; then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
+printf %s "checking for working vfork... " >&6; }
+if test ${ac_cv_func_vfork_works+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "$cross_compiling" = yes
+then :
   ac_cv_func_vfork_works=cross
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 /* Thanks to Paul Eggert for this test.  */
 $ac_includes_default
+#include <signal.h>
 #include <sys/wait.h>
 #ifdef HAVE_VFORK_H
 # include <vfork.h>
 #endif
+
+static void
+do_nothing (int sig)
+{
+  (void) sig;
+}
+
 /* On some sparc systems, changes by the child to local and incoming
    argument registers are propagated back to the parent.  The compiler
    is told about this with #include <vfork.h>, but some compilers
@@ -22282,11 +24633,7 @@ $ac_includes_default
    static variable whose address is put into a register that is
    clobbered by the vfork.  */
 static void
-#ifdef __cplusplus
 sparc_address_test (int arg)
-# else
-sparc_address_test (arg) int arg;
-#endif
 {
   static pid_t child;
   if (!child) {
@@ -22304,13 +24651,18 @@ sparc_address_test (arg) int arg;
 }
 
 int
-main ()
+main (void)
 {
   pid_t parent = getpid ();
   pid_t child;
 
   sparc_address_test (0);
 
+  /* On Solaris 2.4, changes by the child to the signal handler
+     also munge signal handlers in the parent.  To detect this,
+     start by putting the parent's handler in a known state.  */
+  signal (SIGTERM, SIG_DFL);
+
   child = vfork ();
 
   if (child == 0) {
@@ -22332,6 +24684,10 @@ main ()
        || p != p5 || p != p6 || p != p7)
       _exit(1);
 
+    /* Alter the child's signal handler.  */
+    if (signal (SIGTERM, do_nothing) != SIG_DFL)
+      _exit(1);
+
     /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
        from child file descriptors.  If the child closes a descriptor
        before it execs or exits, this munges the parent's descriptor
@@ -22347,6 +24703,9 @@ main ()
         /* Was there some problem with vforking?  */
         child < 0
 
+        /* Did the child munge the parent's signal handler?  */
+        || signal (SIGTERM, SIG_DFL) != SIG_DFL
+
         /* Did the child fail?  (This shouldn't happen.)  */
         || status
 
@@ -22359,9 +24718,10 @@ main ()
   }
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   ac_cv_func_vfork_works=yes
-else
+else $as_nop
   ac_cv_func_vfork_works=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -22369,68 +24729,146 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
-$as_echo "$ac_cv_func_vfork_works" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
+printf "%s\n" "$ac_cv_func_vfork_works" >&6; }
 
 fi;
 if test "x$ac_cv_func_fork_works" = xcross; then
   ac_cv_func_vfork_works=$ac_cv_func_vfork
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
-$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+printf "%s\n" "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
 fi
 
 if test "x$ac_cv_func_vfork_works" = xyes; then
 
-$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
+printf "%s\n" "#define HAVE_WORKING_VFORK 1" >>confdefs.h
 
 else
 
-$as_echo "#define vfork fork" >>confdefs.h
+printf "%s\n" "#define vfork fork" >>confdefs.h
 
 fi
 if test "x$ac_cv_func_fork_works" = xyes; then
 
-$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
+printf "%s\n" "#define HAVE_WORKING_FORK 1" >>confdefs.h
 
 fi
 
 # Don't check realloc, since LeakSanitizer detects memory leak during check
 # AC_FUNC_REALLOC
-ac_fn_c_check_decl "$LINENO" "strerror_r" "ac_cv_have_decl_strerror_r" "$ac_includes_default"
-if test "x$ac_cv_have_decl_strerror_r" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5
+printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; }
+if test ${ac_cv_c_undeclared_builtin_options+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_CFLAGS=$CFLAGS
+   ac_cv_c_undeclared_builtin_options='cannot detect'
+   for ac_arg in '' -fno-builtin; do
+     CFLAGS="$ac_save_CFLAGS $ac_arg"
+     # This test program should *not* compile successfully.
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+(void) strchr;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else $as_nop
+  # This test program should compile successfully.
+        # No library function is consistently available on
+        # freestanding implementations, so test against a dummy
+        # declaration.  Include always-available headers on the
+        # off chance that they somehow elicit warnings.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <float.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stddef.h>
+extern void ac_decl (int, char *);
+
+int
+main (void)
+{
+(void) ac_decl (0, (char *) 0);
+  (void) ac_decl;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  if test x"$ac_arg" = x
+then :
+  ac_cv_c_undeclared_builtin_options='none needed'
+else $as_nop
+  ac_cv_c_undeclared_builtin_options=$ac_arg
+fi
+          break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+    done
+    CFLAGS=$ac_save_CFLAGS
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5
+printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; }
+  case $ac_cv_c_undeclared_builtin_options in #(
+  'cannot detect') :
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot make $CC report undeclared builtins
+See \`config.log' for more details" "$LINENO" 5; } ;; #(
+  'none needed') :
+    ac_c_undeclared_builtin_options='' ;; #(
+  *) :
+    ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;;
+esac
+
+ac_fn_check_decl "$LINENO" "strerror_r" "ac_cv_have_decl_strerror_r" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS"
+if test "x$ac_cv_have_decl_strerror_r" = xyes
+then :
   ac_have_decl=1
-else
+else $as_nop
   ac_have_decl=0
 fi
+printf "%s\n" "#define HAVE_DECL_STRERROR_R $ac_have_decl" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_STRERROR_R $ac_have_decl
-_ACEOF
 
-for ac_func in strerror_r
-do :
-  ac_fn_c_check_func "$LINENO" "strerror_r" "ac_cv_func_strerror_r"
-if test "x$ac_cv_func_strerror_r" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_STRERROR_R 1
-_ACEOF
+if test $ac_cv_have_decl_strerror_r = yes; then
+  # For backward compatibility's sake, define HAVE_STRERROR_R.
+  # (We used to run AC_CHECK_FUNCS_ONCE for strerror_r, as well
+  # as AC_CHECK_DECLS_ONCE.)
+
+printf "%s\n" "#define HAVE_STRERROR_R 1" >>confdefs.h
 
 fi
-done
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strerror_r returns char *" >&5
-$as_echo_n "checking whether strerror_r returns char *... " >&6; }
-if ${ac_cv_func_strerror_r_char_p+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether strerror_r returns char *" >&5
+printf %s "checking whether strerror_r returns char *... " >&6; }
+if test ${ac_cv_func_strerror_r_char_p+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
     ac_cv_func_strerror_r_char_p=no
     if test $ac_cv_have_decl_strerror_r = yes; then
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
+#include <string.h>
 int
-main ()
+main (void)
 {
 
          char buf[100];
@@ -22442,69 +24880,42 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_func_strerror_r_char_p=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    else
-      # strerror_r is not declared.  Choose between
-      # systems that have relatively inaccessible declarations for the
-      # function.  BeOS and DEC UNIX 4.0 fall in this category, but the
-      # former has a strerror_r that returns char*, while the latter
-      # has a strerror_r that returns `int'.
-      # This test should segfault on the DEC system.
-      if test "$cross_compiling" = yes; then :
-  :
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$ac_includes_default
-       extern char *strerror_r ();
-int
-main ()
-{
-char buf[100];
-         char x = *strerror_r (0, buf, sizeof buf);
-         return ! isalpha (x);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_func_strerror_r_char_p=yes
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 
     fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strerror_r_char_p" >&5
-$as_echo "$ac_cv_func_strerror_r_char_p" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strerror_r_char_p" >&5
+printf "%s\n" "$ac_cv_func_strerror_r_char_p" >&6; }
 if test $ac_cv_func_strerror_r_char_p = yes; then
 
-$as_echo "#define STRERROR_R_CHAR_P 1" >>confdefs.h
+printf "%s\n" "#define STRERROR_R_CHAR_P 1" >>confdefs.h
 
 fi
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strnlen" >&5
-$as_echo_n "checking for working strnlen... " >&6; }
-if ${ac_cv_func_strnlen_working+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "$cross_compiling" = yes; then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working strnlen" >&5
+printf %s "checking for working strnlen... " >&6; }
+if test ${ac_cv_func_strnlen_working+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "$cross_compiling" = yes
+then :
   # Guess no on AIX systems, yes otherwise.
                case "$host_os" in
                  aix*) ac_cv_func_strnlen_working=no;;
                  *)    ac_cv_func_strnlen_working=yes;;
                esac
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
 int
-main ()
+main (void)
 {
 
 #define S "foobar"
@@ -22526,9 +24937,10 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   ac_cv_func_strnlen_working=yes
-else
+else $as_nop
   ac_cv_func_strnlen_working=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -22536,8 +24948,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strnlen_working" >&5
-$as_echo "$ac_cv_func_strnlen_working" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strnlen_working" >&5
+printf "%s\n" "$ac_cv_func_strnlen_working" >&6; }
 test $ac_cv_func_strnlen_working = no && case " $LIBOBJS " in
   *" strnlen.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS strnlen.$ac_objext"
@@ -22546,46 +24958,135 @@ esac
 
 
 
-for ac_func in  \
-  _Exit \
-  accept4 \
-  dup2 \
-  getcwd \
-  getpwnam \
-  localtime_r \
-  memchr \
-  memmove \
-  memset \
-  mkostemp \
-  socket \
-  sqrt \
-  strchr \
-  strdup \
-  strerror \
-  strndup \
-  strstr \
-  strtol \
-  strtoul \
-  timegm \
-
-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "_Exit" "ac_cv_func__Exit"
+if test "x$ac_cv_func__Exit" = xyes
+then :
+  printf "%s\n" "#define HAVE__EXIT 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "accept4" "ac_cv_func_accept4"
+if test "x$ac_cv_func_accept4" = xyes
+then :
+  printf "%s\n" "#define HAVE_ACCEPT4 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "dup2" "ac_cv_func_dup2"
+if test "x$ac_cv_func_dup2" = xyes
+then :
+  printf "%s\n" "#define HAVE_DUP2 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd"
+if test "x$ac_cv_func_getcwd" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETCWD 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "getpwnam" "ac_cv_func_getpwnam"
+if test "x$ac_cv_func_getpwnam" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETPWNAM 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r"
+if test "x$ac_cv_func_localtime_r" = xyes
+then :
+  printf "%s\n" "#define HAVE_LOCALTIME_R 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "memchr" "ac_cv_func_memchr"
+if test "x$ac_cv_func_memchr" = xyes
+then :
+  printf "%s\n" "#define HAVE_MEMCHR 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove"
+if test "x$ac_cv_func_memmove" = xyes
+then :
+  printf "%s\n" "#define HAVE_MEMMOVE 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "memset" "ac_cv_func_memset"
+if test "x$ac_cv_func_memset" = xyes
+then :
+  printf "%s\n" "#define HAVE_MEMSET 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "mkostemp" "ac_cv_func_mkostemp"
+if test "x$ac_cv_func_mkostemp" = xyes
+then :
+  printf "%s\n" "#define HAVE_MKOSTEMP 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket"
+if test "x$ac_cv_func_socket" = xyes
+then :
+  printf "%s\n" "#define HAVE_SOCKET 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "sqrt" "ac_cv_func_sqrt"
+if test "x$ac_cv_func_sqrt" = xyes
+then :
+  printf "%s\n" "#define HAVE_SQRT 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strchr" "ac_cv_func_strchr"
+if test "x$ac_cv_func_strchr" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRCHR 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup"
+if test "x$ac_cv_func_strdup" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRDUP 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror"
+if test "x$ac_cv_func_strerror" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRERROR 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strndup" "ac_cv_func_strndup"
+if test "x$ac_cv_func_strndup" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRNDUP 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strstr" "ac_cv_func_strstr"
+if test "x$ac_cv_func_strstr" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRSTR 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strtol" "ac_cv_func_strtol"
+if test "x$ac_cv_func_strtol" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRTOL 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strtoul" "ac_cv_func_strtoul"
+if test "x$ac_cv_func_strtoul" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRTOUL 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "timegm" "ac_cv_func_timegm"
+if test "x$ac_cv_func_timegm" = xyes
+then :
+  printf "%s\n" "#define HAVE_TIMEGM 1" >>confdefs.h
 
 fi
-done
 
 
 # timerfd_create was added in linux kernel 2.6.25
 
 ac_fn_c_check_func "$LINENO" "timerfd_create" "ac_cv_func_timerfd_create"
-if test "x$ac_cv_func_timerfd_create" = xyes; then :
+if test "x$ac_cv_func_timerfd_create" = xyes
+then :
   have_timerfd_create=yes
-else
+else $as_nop
   have_timerfd_create=no
 fi
 
 # For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but
 # cygwin disables initgroups due to feature test macro magic with our
 # configuration.  FreeBSD declares initgroups() in unistd.h.
-ac_fn_c_check_decl "$LINENO" "initgroups" "ac_cv_have_decl_initgroups" "
+ac_fn_check_decl "$LINENO" "initgroups" "ac_cv_have_decl_initgroups" "
   #ifdef HAVE_UNISTD_H
   # include <unistd.h>
   #endif
   #include <grp.h>
 
-"
-if test "x$ac_cv_have_decl_initgroups" = xyes; then :
+" "$ac_c_undeclared_builtin_options" "CFLAGS"
+if test "x$ac_cv_have_decl_initgroups" = xyes
+then :
   ac_have_decl=1
-else
+else $as_nop
   ac_have_decl=0
 fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_INITGROUPS $ac_have_decl
-_ACEOF
+printf "%s\n" "#define HAVE_DECL_INITGROUPS $ac_have_decl" >>confdefs.h
 
 
 save_CFLAGS=$CFLAGS
@@ -22619,11 +25118,12 @@ CXXFLAGS=
 
 if test "x$werror" != "xno"; then
     # For C compiler
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wall" >&5
-$as_echo_n "checking whether C compiler accepts -Wall... " >&6; }
-if ${ax_cv_check_cflags___Wall+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wall" >&5
+printf %s "checking whether C compiler accepts -Wall... " >&6; }
+if test ${ax_cv_check_cflags___Wall+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wall"
@@ -22631,34 +25131,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wall=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wall=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wall" >&5
-$as_echo "$ax_cv_check_cflags___Wall" >&6; }
-if test "x$ax_cv_check_cflags___Wall" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wall" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wall" >&6; }
+if test "x$ax_cv_check_cflags___Wall" = xyes
+then :
   CFLAGS="$CFLAGS -Wall"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wextra" >&5
-$as_echo_n "checking whether C compiler accepts -Wextra... " >&6; }
-if ${ax_cv_check_cflags___Wextra+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wextra" >&5
+printf %s "checking whether C compiler accepts -Wextra... " >&6; }
+if test ${ax_cv_check_cflags___Wextra+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wextra"
@@ -22666,34 +25169,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wextra=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wextra=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wextra" >&5
-$as_echo "$ax_cv_check_cflags___Wextra" >&6; }
-if test "x$ax_cv_check_cflags___Wextra" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wextra" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wextra" >&6; }
+if test "x$ax_cv_check_cflags___Wextra" = xyes
+then :
   CFLAGS="$CFLAGS -Wextra"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Werror" >&5
-$as_echo_n "checking whether C compiler accepts -Werror... " >&6; }
-if ${ax_cv_check_cflags___Werror+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Werror" >&5
+printf %s "checking whether C compiler accepts -Werror... " >&6; }
+if test ${ax_cv_check_cflags___Werror+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Werror"
@@ -22701,34 +25207,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Werror=yes
-else
+else $as_nop
   ax_cv_check_cflags___Werror=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Werror" >&5
-$as_echo "$ax_cv_check_cflags___Werror" >&6; }
-if test "x$ax_cv_check_cflags___Werror" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Werror" >&5
+printf "%s\n" "$ax_cv_check_cflags___Werror" >&6; }
+if test "x$ax_cv_check_cflags___Werror" = xyes
+then :
   CFLAGS="$CFLAGS -Werror"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wmissing-prototypes" >&5
-$as_echo_n "checking whether C compiler accepts -Wmissing-prototypes... " >&6; }
-if ${ax_cv_check_cflags___Wmissing_prototypes+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wmissing-prototypes" >&5
+printf %s "checking whether C compiler accepts -Wmissing-prototypes... " >&6; }
+if test ${ax_cv_check_cflags___Wmissing_prototypes+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wmissing-prototypes"
@@ -22736,34 +25245,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wmissing_prototypes=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wmissing_prototypes=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wmissing_prototypes" >&5
-$as_echo "$ax_cv_check_cflags___Wmissing_prototypes" >&6; }
-if test "x$ax_cv_check_cflags___Wmissing_prototypes" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wmissing_prototypes" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wmissing_prototypes" >&6; }
+if test "x$ax_cv_check_cflags___Wmissing_prototypes" = xyes
+then :
   CFLAGS="$CFLAGS -Wmissing-prototypes"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wstrict-prototypes" >&5
-$as_echo_n "checking whether C compiler accepts -Wstrict-prototypes... " >&6; }
-if ${ax_cv_check_cflags___Wstrict_prototypes+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wstrict-prototypes" >&5
+printf %s "checking whether C compiler accepts -Wstrict-prototypes... " >&6; }
+if test ${ax_cv_check_cflags___Wstrict_prototypes+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wstrict-prototypes"
@@ -22771,34 +25283,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wstrict_prototypes=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wstrict_prototypes=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wstrict_prototypes" >&5
-$as_echo "$ax_cv_check_cflags___Wstrict_prototypes" >&6; }
-if test "x$ax_cv_check_cflags___Wstrict_prototypes" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wstrict_prototypes" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wstrict_prototypes" >&6; }
+if test "x$ax_cv_check_cflags___Wstrict_prototypes" = xyes
+then :
   CFLAGS="$CFLAGS -Wstrict-prototypes"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wmissing-declarations" >&5
-$as_echo_n "checking whether C compiler accepts -Wmissing-declarations... " >&6; }
-if ${ax_cv_check_cflags___Wmissing_declarations+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wmissing-declarations" >&5
+printf %s "checking whether C compiler accepts -Wmissing-declarations... " >&6; }
+if test ${ax_cv_check_cflags___Wmissing_declarations+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wmissing-declarations"
@@ -22806,34 +25321,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wmissing_declarations=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wmissing_declarations=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wmissing_declarations" >&5
-$as_echo "$ax_cv_check_cflags___Wmissing_declarations" >&6; }
-if test "x$ax_cv_check_cflags___Wmissing_declarations" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wmissing_declarations" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wmissing_declarations" >&6; }
+if test "x$ax_cv_check_cflags___Wmissing_declarations" = xyes
+then :
   CFLAGS="$CFLAGS -Wmissing-declarations"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wpointer-arith" >&5
-$as_echo_n "checking whether C compiler accepts -Wpointer-arith... " >&6; }
-if ${ax_cv_check_cflags___Wpointer_arith+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wpointer-arith" >&5
+printf %s "checking whether C compiler accepts -Wpointer-arith... " >&6; }
+if test ${ax_cv_check_cflags___Wpointer_arith+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wpointer-arith"
@@ -22841,34 +25359,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wpointer_arith=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wpointer_arith=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wpointer_arith" >&5
-$as_echo "$ax_cv_check_cflags___Wpointer_arith" >&6; }
-if test "x$ax_cv_check_cflags___Wpointer_arith" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wpointer_arith" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wpointer_arith" >&6; }
+if test "x$ax_cv_check_cflags___Wpointer_arith" = xyes
+then :
   CFLAGS="$CFLAGS -Wpointer-arith"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wdeclaration-after-statement" >&5
-$as_echo_n "checking whether C compiler accepts -Wdeclaration-after-statement... " >&6; }
-if ${ax_cv_check_cflags___Wdeclaration_after_statement+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wdeclaration-after-statement" >&5
+printf %s "checking whether C compiler accepts -Wdeclaration-after-statement... " >&6; }
+if test ${ax_cv_check_cflags___Wdeclaration_after_statement+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wdeclaration-after-statement"
@@ -22876,34 +25397,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wdeclaration_after_statement=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wdeclaration_after_statement=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wdeclaration_after_statement" >&5
-$as_echo "$ax_cv_check_cflags___Wdeclaration_after_statement" >&6; }
-if test "x$ax_cv_check_cflags___Wdeclaration_after_statement" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wdeclaration_after_statement" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wdeclaration_after_statement" >&6; }
+if test "x$ax_cv_check_cflags___Wdeclaration_after_statement" = xyes
+then :
   CFLAGS="$CFLAGS -Wdeclaration-after-statement"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wformat-security" >&5
-$as_echo_n "checking whether C compiler accepts -Wformat-security... " >&6; }
-if ${ax_cv_check_cflags___Wformat_security+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wformat-security" >&5
+printf %s "checking whether C compiler accepts -Wformat-security... " >&6; }
+if test ${ax_cv_check_cflags___Wformat_security+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wformat-security"
@@ -22911,34 +25435,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wformat_security=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wformat_security=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wformat_security" >&5
-$as_echo "$ax_cv_check_cflags___Wformat_security" >&6; }
-if test "x$ax_cv_check_cflags___Wformat_security" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wformat_security" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wformat_security" >&6; }
+if test "x$ax_cv_check_cflags___Wformat_security" = xyes
+then :
   CFLAGS="$CFLAGS -Wformat-security"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wwrite-strings" >&5
-$as_echo_n "checking whether C compiler accepts -Wwrite-strings... " >&6; }
-if ${ax_cv_check_cflags___Wwrite_strings+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wwrite-strings" >&5
+printf %s "checking whether C compiler accepts -Wwrite-strings... " >&6; }
+if test ${ax_cv_check_cflags___Wwrite_strings+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wwrite-strings"
@@ -22946,34 +25473,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wwrite_strings=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wwrite_strings=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wwrite_strings" >&5
-$as_echo "$ax_cv_check_cflags___Wwrite_strings" >&6; }
-if test "x$ax_cv_check_cflags___Wwrite_strings" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wwrite_strings" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wwrite_strings" >&6; }
+if test "x$ax_cv_check_cflags___Wwrite_strings" = xyes
+then :
   CFLAGS="$CFLAGS -Wwrite-strings"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wshadow" >&5
-$as_echo_n "checking whether C compiler accepts -Wshadow... " >&6; }
-if ${ax_cv_check_cflags___Wshadow+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wshadow" >&5
+printf %s "checking whether C compiler accepts -Wshadow... " >&6; }
+if test ${ax_cv_check_cflags___Wshadow+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wshadow"
@@ -22981,34 +25511,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wshadow=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wshadow=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wshadow" >&5
-$as_echo "$ax_cv_check_cflags___Wshadow" >&6; }
-if test "x$ax_cv_check_cflags___Wshadow" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wshadow" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wshadow" >&6; }
+if test "x$ax_cv_check_cflags___Wshadow" = xyes
+then :
   CFLAGS="$CFLAGS -Wshadow"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Winline" >&5
-$as_echo_n "checking whether C compiler accepts -Winline... " >&6; }
-if ${ax_cv_check_cflags___Winline+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Winline" >&5
+printf %s "checking whether C compiler accepts -Winline... " >&6; }
+if test ${ax_cv_check_cflags___Winline+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Winline"
@@ -23016,34 +25549,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Winline=yes
-else
+else $as_nop
   ax_cv_check_cflags___Winline=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Winline" >&5
-$as_echo "$ax_cv_check_cflags___Winline" >&6; }
-if test "x$ax_cv_check_cflags___Winline" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Winline" >&5
+printf "%s\n" "$ax_cv_check_cflags___Winline" >&6; }
+if test "x$ax_cv_check_cflags___Winline" = xyes
+then :
   CFLAGS="$CFLAGS -Winline"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wnested-externs" >&5
-$as_echo_n "checking whether C compiler accepts -Wnested-externs... " >&6; }
-if ${ax_cv_check_cflags___Wnested_externs+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wnested-externs" >&5
+printf %s "checking whether C compiler accepts -Wnested-externs... " >&6; }
+if test ${ax_cv_check_cflags___Wnested_externs+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wnested-externs"
@@ -23051,34 +25587,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wnested_externs=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wnested_externs=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wnested_externs" >&5
-$as_echo "$ax_cv_check_cflags___Wnested_externs" >&6; }
-if test "x$ax_cv_check_cflags___Wnested_externs" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wnested_externs" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wnested_externs" >&6; }
+if test "x$ax_cv_check_cflags___Wnested_externs" = xyes
+then :
   CFLAGS="$CFLAGS -Wnested-externs"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wfloat-equal" >&5
-$as_echo_n "checking whether C compiler accepts -Wfloat-equal... " >&6; }
-if ${ax_cv_check_cflags___Wfloat_equal+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wfloat-equal" >&5
+printf %s "checking whether C compiler accepts -Wfloat-equal... " >&6; }
+if test ${ax_cv_check_cflags___Wfloat_equal+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wfloat-equal"
@@ -23086,34 +25625,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wfloat_equal=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wfloat_equal=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wfloat_equal" >&5
-$as_echo "$ax_cv_check_cflags___Wfloat_equal" >&6; }
-if test "x$ax_cv_check_cflags___Wfloat_equal" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wfloat_equal" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wfloat_equal" >&6; }
+if test "x$ax_cv_check_cflags___Wfloat_equal" = xyes
+then :
   CFLAGS="$CFLAGS -Wfloat-equal"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wundef" >&5
-$as_echo_n "checking whether C compiler accepts -Wundef... " >&6; }
-if ${ax_cv_check_cflags___Wundef+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wundef" >&5
+printf %s "checking whether C compiler accepts -Wundef... " >&6; }
+if test ${ax_cv_check_cflags___Wundef+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wundef"
@@ -23121,34 +25663,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wundef=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wundef=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wundef" >&5
-$as_echo "$ax_cv_check_cflags___Wundef" >&6; }
-if test "x$ax_cv_check_cflags___Wundef" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wundef" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wundef" >&6; }
+if test "x$ax_cv_check_cflags___Wundef" = xyes
+then :
   CFLAGS="$CFLAGS -Wundef"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wendif-labels" >&5
-$as_echo_n "checking whether C compiler accepts -Wendif-labels... " >&6; }
-if ${ax_cv_check_cflags___Wendif_labels+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wendif-labels" >&5
+printf %s "checking whether C compiler accepts -Wendif-labels... " >&6; }
+if test ${ax_cv_check_cflags___Wendif_labels+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wendif-labels"
@@ -23156,34 +25701,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wendif_labels=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wendif_labels=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wendif_labels" >&5
-$as_echo "$ax_cv_check_cflags___Wendif_labels" >&6; }
-if test "x$ax_cv_check_cflags___Wendif_labels" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wendif_labels" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wendif_labels" >&6; }
+if test "x$ax_cv_check_cflags___Wendif_labels" = xyes
+then :
   CFLAGS="$CFLAGS -Wendif-labels"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wempty-body" >&5
-$as_echo_n "checking whether C compiler accepts -Wempty-body... " >&6; }
-if ${ax_cv_check_cflags___Wempty_body+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wempty-body" >&5
+printf %s "checking whether C compiler accepts -Wempty-body... " >&6; }
+if test ${ax_cv_check_cflags___Wempty_body+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wempty-body"
@@ -23191,34 +25739,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wempty_body=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wempty_body=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wempty_body" >&5
-$as_echo "$ax_cv_check_cflags___Wempty_body" >&6; }
-if test "x$ax_cv_check_cflags___Wempty_body" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wempty_body" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wempty_body" >&6; }
+if test "x$ax_cv_check_cflags___Wempty_body" = xyes
+then :
   CFLAGS="$CFLAGS -Wempty-body"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wcast-align" >&5
-$as_echo_n "checking whether C compiler accepts -Wcast-align... " >&6; }
-if ${ax_cv_check_cflags___Wcast_align+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wcast-align" >&5
+printf %s "checking whether C compiler accepts -Wcast-align... " >&6; }
+if test ${ax_cv_check_cflags___Wcast_align+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wcast-align"
@@ -23226,34 +25777,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wcast_align=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wcast_align=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wcast_align" >&5
-$as_echo "$ax_cv_check_cflags___Wcast_align" >&6; }
-if test "x$ax_cv_check_cflags___Wcast_align" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wcast_align" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wcast_align" >&6; }
+if test "x$ax_cv_check_cflags___Wcast_align" = xyes
+then :
   CFLAGS="$CFLAGS -Wcast-align"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wclobbered" >&5
-$as_echo_n "checking whether C compiler accepts -Wclobbered... " >&6; }
-if ${ax_cv_check_cflags___Wclobbered+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wclobbered" >&5
+printf %s "checking whether C compiler accepts -Wclobbered... " >&6; }
+if test ${ax_cv_check_cflags___Wclobbered+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wclobbered"
@@ -23261,34 +25815,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wclobbered=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wclobbered=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wclobbered" >&5
-$as_echo "$ax_cv_check_cflags___Wclobbered" >&6; }
-if test "x$ax_cv_check_cflags___Wclobbered" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wclobbered" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wclobbered" >&6; }
+if test "x$ax_cv_check_cflags___Wclobbered" = xyes
+then :
   CFLAGS="$CFLAGS -Wclobbered"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wvla" >&5
-$as_echo_n "checking whether C compiler accepts -Wvla... " >&6; }
-if ${ax_cv_check_cflags___Wvla+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wvla" >&5
+printf %s "checking whether C compiler accepts -Wvla... " >&6; }
+if test ${ax_cv_check_cflags___Wvla+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wvla"
@@ -23296,34 +25853,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wvla=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wvla=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wvla" >&5
-$as_echo "$ax_cv_check_cflags___Wvla" >&6; }
-if test "x$ax_cv_check_cflags___Wvla" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wvla" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wvla" >&6; }
+if test "x$ax_cv_check_cflags___Wvla" = xyes
+then :
   CFLAGS="$CFLAGS -Wvla"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wpragmas" >&5
-$as_echo_n "checking whether C compiler accepts -Wpragmas... " >&6; }
-if ${ax_cv_check_cflags___Wpragmas+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wpragmas" >&5
+printf %s "checking whether C compiler accepts -Wpragmas... " >&6; }
+if test ${ax_cv_check_cflags___Wpragmas+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wpragmas"
@@ -23331,34 +25891,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wpragmas=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wpragmas=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wpragmas" >&5
-$as_echo "$ax_cv_check_cflags___Wpragmas" >&6; }
-if test "x$ax_cv_check_cflags___Wpragmas" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wpragmas" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wpragmas" >&6; }
+if test "x$ax_cv_check_cflags___Wpragmas" = xyes
+then :
   CFLAGS="$CFLAGS -Wpragmas"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wunreachable-code" >&5
-$as_echo_n "checking whether C compiler accepts -Wunreachable-code... " >&6; }
-if ${ax_cv_check_cflags___Wunreachable_code+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wunreachable-code" >&5
+printf %s "checking whether C compiler accepts -Wunreachable-code... " >&6; }
+if test ${ax_cv_check_cflags___Wunreachable_code+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wunreachable-code"
@@ -23366,34 +25929,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wunreachable_code=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wunreachable_code=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wunreachable_code" >&5
-$as_echo "$ax_cv_check_cflags___Wunreachable_code" >&6; }
-if test "x$ax_cv_check_cflags___Wunreachable_code" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wunreachable_code" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wunreachable_code" >&6; }
+if test "x$ax_cv_check_cflags___Wunreachable_code" = xyes
+then :
   CFLAGS="$CFLAGS -Wunreachable-code"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Waddress" >&5
-$as_echo_n "checking whether C compiler accepts -Waddress... " >&6; }
-if ${ax_cv_check_cflags___Waddress+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Waddress" >&5
+printf %s "checking whether C compiler accepts -Waddress... " >&6; }
+if test ${ax_cv_check_cflags___Waddress+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Waddress"
@@ -23401,34 +25967,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Waddress=yes
-else
+else $as_nop
   ax_cv_check_cflags___Waddress=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Waddress" >&5
-$as_echo "$ax_cv_check_cflags___Waddress" >&6; }
-if test "x$ax_cv_check_cflags___Waddress" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Waddress" >&5
+printf "%s\n" "$ax_cv_check_cflags___Waddress" >&6; }
+if test "x$ax_cv_check_cflags___Waddress" = xyes
+then :
   CFLAGS="$CFLAGS -Waddress"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wattributes" >&5
-$as_echo_n "checking whether C compiler accepts -Wattributes... " >&6; }
-if ${ax_cv_check_cflags___Wattributes+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wattributes" >&5
+printf %s "checking whether C compiler accepts -Wattributes... " >&6; }
+if test ${ax_cv_check_cflags___Wattributes+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wattributes"
@@ -23436,34 +26005,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wattributes=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wattributes=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wattributes" >&5
-$as_echo "$ax_cv_check_cflags___Wattributes" >&6; }
-if test "x$ax_cv_check_cflags___Wattributes" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wattributes" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wattributes" >&6; }
+if test "x$ax_cv_check_cflags___Wattributes" = xyes
+then :
   CFLAGS="$CFLAGS -Wattributes"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wdiv-by-zero" >&5
-$as_echo_n "checking whether C compiler accepts -Wdiv-by-zero... " >&6; }
-if ${ax_cv_check_cflags___Wdiv_by_zero+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wdiv-by-zero" >&5
+printf %s "checking whether C compiler accepts -Wdiv-by-zero... " >&6; }
+if test ${ax_cv_check_cflags___Wdiv_by_zero+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wdiv-by-zero"
@@ -23471,34 +26043,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wdiv_by_zero=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wdiv_by_zero=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wdiv_by_zero" >&5
-$as_echo "$ax_cv_check_cflags___Wdiv_by_zero" >&6; }
-if test "x$ax_cv_check_cflags___Wdiv_by_zero" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wdiv_by_zero" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wdiv_by_zero" >&6; }
+if test "x$ax_cv_check_cflags___Wdiv_by_zero" = xyes
+then :
   CFLAGS="$CFLAGS -Wdiv-by-zero"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wshorten-64-to-32" >&5
-$as_echo_n "checking whether C compiler accepts -Wshorten-64-to-32... " >&6; }
-if ${ax_cv_check_cflags___Wshorten_64_to_32+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wshorten-64-to-32" >&5
+printf %s "checking whether C compiler accepts -Wshorten-64-to-32... " >&6; }
+if test ${ax_cv_check_cflags___Wshorten_64_to_32+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wshorten-64-to-32"
@@ -23506,35 +26081,38 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wshorten_64_to_32=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wshorten_64_to_32=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wshorten_64_to_32" >&5
-$as_echo "$ax_cv_check_cflags___Wshorten_64_to_32" >&6; }
-if test "x$ax_cv_check_cflags___Wshorten_64_to_32" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wshorten_64_to_32" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wshorten_64_to_32" >&6; }
+if test "x$ax_cv_check_cflags___Wshorten_64_to_32" = xyes
+then :
   CFLAGS="$CFLAGS -Wshorten-64-to-32"
-else
+else $as_nop
   :
 fi
 
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wconversion" >&5
-$as_echo_n "checking whether C compiler accepts -Wconversion... " >&6; }
-if ${ax_cv_check_cflags___Wconversion+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wconversion" >&5
+printf %s "checking whether C compiler accepts -Wconversion... " >&6; }
+if test ${ax_cv_check_cflags___Wconversion+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wconversion"
@@ -23542,34 +26120,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wconversion=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wconversion=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wconversion" >&5
-$as_echo "$ax_cv_check_cflags___Wconversion" >&6; }
-if test "x$ax_cv_check_cflags___Wconversion" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wconversion" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wconversion" >&6; }
+if test "x$ax_cv_check_cflags___Wconversion" = xyes
+then :
   CFLAGS="$CFLAGS -Wconversion"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wextended-offsetof" >&5
-$as_echo_n "checking whether C compiler accepts -Wextended-offsetof... " >&6; }
-if ${ax_cv_check_cflags___Wextended_offsetof+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wextended-offsetof" >&5
+printf %s "checking whether C compiler accepts -Wextended-offsetof... " >&6; }
+if test ${ax_cv_check_cflags___Wextended_offsetof+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wextended-offsetof"
@@ -23577,34 +26158,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wextended_offsetof=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wextended_offsetof=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wextended_offsetof" >&5
-$as_echo "$ax_cv_check_cflags___Wextended_offsetof" >&6; }
-if test "x$ax_cv_check_cflags___Wextended_offsetof" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wextended_offsetof" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wextended_offsetof" >&6; }
+if test "x$ax_cv_check_cflags___Wextended_offsetof" = xyes
+then :
   CFLAGS="$CFLAGS -Wextended-offsetof"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wformat-nonliteral" >&5
-$as_echo_n "checking whether C compiler accepts -Wformat-nonliteral... " >&6; }
-if ${ax_cv_check_cflags___Wformat_nonliteral+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wformat-nonliteral" >&5
+printf %s "checking whether C compiler accepts -Wformat-nonliteral... " >&6; }
+if test ${ax_cv_check_cflags___Wformat_nonliteral+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wformat-nonliteral"
@@ -23612,34 +26196,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wformat_nonliteral=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wformat_nonliteral=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wformat_nonliteral" >&5
-$as_echo "$ax_cv_check_cflags___Wformat_nonliteral" >&6; }
-if test "x$ax_cv_check_cflags___Wformat_nonliteral" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wformat_nonliteral" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wformat_nonliteral" >&6; }
+if test "x$ax_cv_check_cflags___Wformat_nonliteral" = xyes
+then :
   CFLAGS="$CFLAGS -Wformat-nonliteral"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wlanguage-extension-token" >&5
-$as_echo_n "checking whether C compiler accepts -Wlanguage-extension-token... " >&6; }
-if ${ax_cv_check_cflags___Wlanguage_extension_token+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wlanguage-extension-token" >&5
+printf %s "checking whether C compiler accepts -Wlanguage-extension-token... " >&6; }
+if test ${ax_cv_check_cflags___Wlanguage_extension_token+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wlanguage-extension-token"
@@ -23647,34 +26234,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wlanguage_extension_token=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wlanguage_extension_token=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wlanguage_extension_token" >&5
-$as_echo "$ax_cv_check_cflags___Wlanguage_extension_token" >&6; }
-if test "x$ax_cv_check_cflags___Wlanguage_extension_token" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wlanguage_extension_token" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wlanguage_extension_token" >&6; }
+if test "x$ax_cv_check_cflags___Wlanguage_extension_token" = xyes
+then :
   CFLAGS="$CFLAGS -Wlanguage-extension-token"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wmissing-field-initializers" >&5
-$as_echo_n "checking whether C compiler accepts -Wmissing-field-initializers... " >&6; }
-if ${ax_cv_check_cflags___Wmissing_field_initializers+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wmissing-field-initializers" >&5
+printf %s "checking whether C compiler accepts -Wmissing-field-initializers... " >&6; }
+if test ${ax_cv_check_cflags___Wmissing_field_initializers+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wmissing-field-initializers"
@@ -23682,34 +26272,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wmissing_field_initializers=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wmissing_field_initializers=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wmissing_field_initializers" >&5
-$as_echo "$ax_cv_check_cflags___Wmissing_field_initializers" >&6; }
-if test "x$ax_cv_check_cflags___Wmissing_field_initializers" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wmissing_field_initializers" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wmissing_field_initializers" >&6; }
+if test "x$ax_cv_check_cflags___Wmissing_field_initializers" = xyes
+then :
   CFLAGS="$CFLAGS -Wmissing-field-initializers"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wmissing-noreturn" >&5
-$as_echo_n "checking whether C compiler accepts -Wmissing-noreturn... " >&6; }
-if ${ax_cv_check_cflags___Wmissing_noreturn+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wmissing-noreturn" >&5
+printf %s "checking whether C compiler accepts -Wmissing-noreturn... " >&6; }
+if test ${ax_cv_check_cflags___Wmissing_noreturn+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wmissing-noreturn"
@@ -23717,34 +26310,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wmissing_noreturn=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wmissing_noreturn=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wmissing_noreturn" >&5
-$as_echo "$ax_cv_check_cflags___Wmissing_noreturn" >&6; }
-if test "x$ax_cv_check_cflags___Wmissing_noreturn" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wmissing_noreturn" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wmissing_noreturn" >&6; }
+if test "x$ax_cv_check_cflags___Wmissing_noreturn" = xyes
+then :
   CFLAGS="$CFLAGS -Wmissing-noreturn"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wmissing-variable-declarations" >&5
-$as_echo_n "checking whether C compiler accepts -Wmissing-variable-declarations... " >&6; }
-if ${ax_cv_check_cflags___Wmissing_variable_declarations+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wmissing-variable-declarations" >&5
+printf %s "checking whether C compiler accepts -Wmissing-variable-declarations... " >&6; }
+if test ${ax_cv_check_cflags___Wmissing_variable_declarations+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wmissing-variable-declarations"
@@ -23752,36 +26348,39 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wmissing_variable_declarations=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wmissing_variable_declarations=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wmissing_variable_declarations" >&5
-$as_echo "$ax_cv_check_cflags___Wmissing_variable_declarations" >&6; }
-if test "x$ax_cv_check_cflags___Wmissing_variable_declarations" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wmissing_variable_declarations" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wmissing_variable_declarations" >&6; }
+if test "x$ax_cv_check_cflags___Wmissing_variable_declarations" = xyes
+then :
   CFLAGS="$CFLAGS -Wmissing-variable-declarations"
-else
+else $as_nop
   :
 fi
 
     # Not used because we cannot change public structs
     # AX_CHECK_COMPILE_FLAG([-Wpadded], [CFLAGS="$CFLAGS -Wpadded"])
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wsign-conversion" >&5
-$as_echo_n "checking whether C compiler accepts -Wsign-conversion... " >&6; }
-if ${ax_cv_check_cflags___Wsign_conversion+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wsign-conversion" >&5
+printf %s "checking whether C compiler accepts -Wsign-conversion... " >&6; }
+if test ${ax_cv_check_cflags___Wsign_conversion+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wsign-conversion"
@@ -23789,36 +26388,39 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wsign_conversion=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wsign_conversion=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wsign_conversion" >&5
-$as_echo "$ax_cv_check_cflags___Wsign_conversion" >&6; }
-if test "x$ax_cv_check_cflags___Wsign_conversion" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wsign_conversion" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wsign_conversion" >&6; }
+if test "x$ax_cv_check_cflags___Wsign_conversion" = xyes
+then :
   CFLAGS="$CFLAGS -Wsign-conversion"
-else
+else $as_nop
   :
 fi
 
     # Not used because this basically disallows default case
     # AX_CHECK_COMPILE_FLAG([-Wswitch-enum], [CFLAGS="$CFLAGS -Wswitch-enum"])
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wunreachable-code-break" >&5
-$as_echo_n "checking whether C compiler accepts -Wunreachable-code-break... " >&6; }
-if ${ax_cv_check_cflags___Wunreachable_code_break+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wunreachable-code-break" >&5
+printf %s "checking whether C compiler accepts -Wunreachable-code-break... " >&6; }
+if test ${ax_cv_check_cflags___Wunreachable_code_break+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wunreachable-code-break"
@@ -23826,34 +26428,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wunreachable_code_break=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wunreachable_code_break=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wunreachable_code_break" >&5
-$as_echo "$ax_cv_check_cflags___Wunreachable_code_break" >&6; }
-if test "x$ax_cv_check_cflags___Wunreachable_code_break" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wunreachable_code_break" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wunreachable_code_break" >&6; }
+if test "x$ax_cv_check_cflags___Wunreachable_code_break" = xyes
+then :
   CFLAGS="$CFLAGS -Wunreachable-code-break"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wunused-macros" >&5
-$as_echo_n "checking whether C compiler accepts -Wunused-macros... " >&6; }
-if ${ax_cv_check_cflags___Wunused_macros+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wunused-macros" >&5
+printf %s "checking whether C compiler accepts -Wunused-macros... " >&6; }
+if test ${ax_cv_check_cflags___Wunused_macros+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wunused-macros"
@@ -23861,34 +26466,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wunused_macros=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wunused_macros=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wunused_macros" >&5
-$as_echo "$ax_cv_check_cflags___Wunused_macros" >&6; }
-if test "x$ax_cv_check_cflags___Wunused_macros" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wunused_macros" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wunused_macros" >&6; }
+if test "x$ax_cv_check_cflags___Wunused_macros" = xyes
+then :
   CFLAGS="$CFLAGS -Wunused-macros"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wunused-parameter" >&5
-$as_echo_n "checking whether C compiler accepts -Wunused-parameter... " >&6; }
-if ${ax_cv_check_cflags___Wunused_parameter+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wunused-parameter" >&5
+printf %s "checking whether C compiler accepts -Wunused-parameter... " >&6; }
+if test ${ax_cv_check_cflags___Wunused_parameter+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wunused-parameter"
@@ -23896,34 +26504,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wunused_parameter=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wunused_parameter=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wunused_parameter" >&5
-$as_echo "$ax_cv_check_cflags___Wunused_parameter" >&6; }
-if test "x$ax_cv_check_cflags___Wunused_parameter" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wunused_parameter" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wunused_parameter" >&6; }
+if test "x$ax_cv_check_cflags___Wunused_parameter" = xyes
+then :
   CFLAGS="$CFLAGS -Wunused-parameter"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wredundant-decls" >&5
-$as_echo_n "checking whether C compiler accepts -Wredundant-decls... " >&6; }
-if ${ax_cv_check_cflags___Wredundant_decls+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wredundant-decls" >&5
+printf %s "checking whether C compiler accepts -Wredundant-decls... " >&6; }
+if test ${ax_cv_check_cflags___Wredundant_decls+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wredundant-decls"
@@ -23931,35 +26542,38 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wredundant_decls=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wredundant_decls=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wredundant_decls" >&5
-$as_echo "$ax_cv_check_cflags___Wredundant_decls" >&6; }
-if test "x$ax_cv_check_cflags___Wredundant_decls" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wredundant_decls" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wredundant_decls" >&6; }
+if test "x$ax_cv_check_cflags___Wredundant_decls" = xyes
+then :
   CFLAGS="$CFLAGS -Wredundant-decls"
-else
+else $as_nop
   :
 fi
 
     # Only work with Clang for the moment
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wheader-guard" >&5
-$as_echo_n "checking whether C compiler accepts -Wheader-guard... " >&6; }
-if ${ax_cv_check_cflags___Wheader_guard+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wheader-guard" >&5
+printf %s "checking whether C compiler accepts -Wheader-guard... " >&6; }
+if test ${ax_cv_check_cflags___Wheader_guard+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wheader-guard"
@@ -23967,34 +26581,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wheader_guard=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wheader_guard=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wheader_guard" >&5
-$as_echo "$ax_cv_check_cflags___Wheader_guard" >&6; }
-if test "x$ax_cv_check_cflags___Wheader_guard" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wheader_guard" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wheader_guard" >&6; }
+if test "x$ax_cv_check_cflags___Wheader_guard" = xyes
+then :
   CFLAGS="$CFLAGS -Wheader-guard"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wsometimes-uninitialized" >&5
-$as_echo_n "checking whether C compiler accepts -Wsometimes-uninitialized... " >&6; }
-if ${ax_cv_check_cflags___Wsometimes_uninitialized+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wsometimes-uninitialized" >&5
+printf %s "checking whether C compiler accepts -Wsometimes-uninitialized... " >&6; }
+if test ${ax_cv_check_cflags___Wsometimes_uninitialized+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wsometimes-uninitialized"
@@ -24002,36 +26619,39 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wsometimes_uninitialized=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wsometimes_uninitialized=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wsometimes_uninitialized" >&5
-$as_echo "$ax_cv_check_cflags___Wsometimes_uninitialized" >&6; }
-if test "x$ax_cv_check_cflags___Wsometimes_uninitialized" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wsometimes_uninitialized" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wsometimes_uninitialized" >&6; }
+if test "x$ax_cv_check_cflags___Wsometimes_uninitialized" = xyes
+then :
   CFLAGS="$CFLAGS -Wsometimes-uninitialized"
-else
+else $as_nop
   :
 fi
 
 
     # This is required because we pass format string as "const char*.
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-format-nonliteral" >&5
-$as_echo_n "checking whether C compiler accepts -Wno-format-nonliteral... " >&6; }
-if ${ax_cv_check_cflags___Wno_format_nonliteral+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-format-nonliteral" >&5
+printf %s "checking whether C compiler accepts -Wno-format-nonliteral... " >&6; }
+if test ${ax_cv_check_cflags___Wno_format_nonliteral+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -Wno-format-nonliteral"
@@ -24039,26 +26659,28 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___Wno_format_nonliteral=yes
-else
+else $as_nop
   ax_cv_check_cflags___Wno_format_nonliteral=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wno_format_nonliteral" >&5
-$as_echo "$ax_cv_check_cflags___Wno_format_nonliteral" >&6; }
-if test "x$ax_cv_check_cflags___Wno_format_nonliteral" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wno_format_nonliteral" >&5
+printf "%s\n" "$ax_cv_check_cflags___Wno_format_nonliteral" >&6; }
+if test "x$ax_cv_check_cflags___Wno_format_nonliteral" = xyes
+then :
   CFLAGS="$CFLAGS -Wno-format-nonliteral"
-else
+else $as_nop
   :
 fi
 
@@ -24070,11 +26692,12 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Wall" >&5
-$as_echo_n "checking whether C++ compiler accepts -Wall... " >&6; }
-if ${ax_cv_check_cxxflags___Wall+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Wall" >&5
+printf %s "checking whether C++ compiler accepts -Wall... " >&6; }
+if test ${ax_cv_check_cxxflags___Wall+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CXXFLAGS
   CXXFLAGS="$CXXFLAGS  -Wall"
@@ -24082,34 +26705,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ax_cv_check_cxxflags___Wall=yes
-else
+else $as_nop
   ax_cv_check_cxxflags___Wall=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CXXFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Wall" >&5
-$as_echo "$ax_cv_check_cxxflags___Wall" >&6; }
-if test "x$ax_cv_check_cxxflags___Wall" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Wall" >&5
+printf "%s\n" "$ax_cv_check_cxxflags___Wall" >&6; }
+if test "x$ax_cv_check_cxxflags___Wall" = xyes
+then :
   CXXFLAGS="$CXXFLAGS -Wall"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Werror" >&5
-$as_echo_n "checking whether C++ compiler accepts -Werror... " >&6; }
-if ${ax_cv_check_cxxflags___Werror+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Werror" >&5
+printf %s "checking whether C++ compiler accepts -Werror... " >&6; }
+if test ${ax_cv_check_cxxflags___Werror+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CXXFLAGS
   CXXFLAGS="$CXXFLAGS  -Werror"
@@ -24117,34 +26743,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ax_cv_check_cxxflags___Werror=yes
-else
+else $as_nop
   ax_cv_check_cxxflags___Werror=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CXXFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Werror" >&5
-$as_echo "$ax_cv_check_cxxflags___Werror" >&6; }
-if test "x$ax_cv_check_cxxflags___Werror" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Werror" >&5
+printf "%s\n" "$ax_cv_check_cxxflags___Werror" >&6; }
+if test "x$ax_cv_check_cxxflags___Werror" = xyes
+then :
   CXXFLAGS="$CXXFLAGS -Werror"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Wformat-security" >&5
-$as_echo_n "checking whether C++ compiler accepts -Wformat-security... " >&6; }
-if ${ax_cv_check_cxxflags___Wformat_security+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Wformat-security" >&5
+printf %s "checking whether C++ compiler accepts -Wformat-security... " >&6; }
+if test ${ax_cv_check_cxxflags___Wformat_security+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CXXFLAGS
   CXXFLAGS="$CXXFLAGS  -Wformat-security"
@@ -24152,34 +26781,37 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ax_cv_check_cxxflags___Wformat_security=yes
-else
+else $as_nop
   ax_cv_check_cxxflags___Wformat_security=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CXXFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Wformat_security" >&5
-$as_echo "$ax_cv_check_cxxflags___Wformat_security" >&6; }
-if test "x$ax_cv_check_cxxflags___Wformat_security" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Wformat_security" >&5
+printf "%s\n" "$ax_cv_check_cxxflags___Wformat_security" >&6; }
+if test "x$ax_cv_check_cxxflags___Wformat_security" = xyes
+then :
   CXXFLAGS="$CXXFLAGS -Wformat-security"
-else
+else $as_nop
   :
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Wsometimes-uninitialized" >&5
-$as_echo_n "checking whether C++ compiler accepts -Wsometimes-uninitialized... " >&6; }
-if ${ax_cv_check_cxxflags___Wsometimes_uninitialized+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Wsometimes-uninitialized" >&5
+printf %s "checking whether C++ compiler accepts -Wsometimes-uninitialized... " >&6; }
+if test ${ax_cv_check_cxxflags___Wsometimes_uninitialized+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CXXFLAGS
   CXXFLAGS="$CXXFLAGS  -Wsometimes-uninitialized"
@@ -24187,36 +26819,39 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ax_cv_check_cxxflags___Wsometimes_uninitialized=yes
-else
+else $as_nop
   ax_cv_check_cxxflags___Wsometimes_uninitialized=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CXXFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Wsometimes_uninitialized" >&5
-$as_echo "$ax_cv_check_cxxflags___Wsometimes_uninitialized" >&6; }
-if test "x$ax_cv_check_cxxflags___Wsometimes_uninitialized" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Wsometimes_uninitialized" >&5
+printf "%s\n" "$ax_cv_check_cxxflags___Wsometimes_uninitialized" >&6; }
+if test "x$ax_cv_check_cxxflags___Wsometimes_uninitialized" = xyes
+then :
   CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"
-else
+else $as_nop
   :
 fi
 
     # Disable noexcept-type warning of g++-7.  This is not harmful as
     # long as all source files are compiled with the same compiler.
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Wno-noexcept-type" >&5
-$as_echo_n "checking whether C++ compiler accepts -Wno-noexcept-type... " >&6; }
-if ${ax_cv_check_cxxflags___Wno_noexcept_type+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Wno-noexcept-type" >&5
+printf %s "checking whether C++ compiler accepts -Wno-noexcept-type... " >&6; }
+if test ${ax_cv_check_cxxflags___Wno_noexcept_type+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CXXFLAGS
   CXXFLAGS="$CXXFLAGS  -Wno-noexcept-type"
@@ -24224,26 +26859,28 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ax_cv_check_cxxflags___Wno_noexcept_type=yes
-else
+else $as_nop
   ax_cv_check_cxxflags___Wno_noexcept_type=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CXXFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Wno_noexcept_type" >&5
-$as_echo "$ax_cv_check_cxxflags___Wno_noexcept_type" >&6; }
-if test "x$ax_cv_check_cxxflags___Wno_noexcept_type" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Wno_noexcept_type" >&5
+printf "%s\n" "$ax_cv_check_cxxflags___Wno_noexcept_type" >&6; }
+if test "x$ax_cv_check_cxxflags___Wno_noexcept_type" = xyes
+then :
   CXXFLAGS="$CXXFLAGS -Wno-noexcept-type"
-else
+else $as_nop
   :
 fi
 
@@ -24265,11 +26902,12 @@ CXXFLAGS=$save_CXXFLAGS
 
 
 EXTRACFLAG=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fvisibility=hidden" >&5
-$as_echo_n "checking whether C compiler accepts -fvisibility=hidden... " >&6; }
-if ${ax_cv_check_cflags___fvisibility_hidden+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fvisibility=hidden" >&5
+printf %s "checking whether C compiler accepts -fvisibility=hidden... " >&6; }
+if test ${ax_cv_check_cflags___fvisibility_hidden+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
   ax_check_save_flags=$CFLAGS
   CFLAGS="$CFLAGS  -fvisibility=hidden"
@@ -24277,26 +26915,28 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ax_cv_check_cflags___fvisibility_hidden=yes
-else
+else $as_nop
   ax_cv_check_cflags___fvisibility_hidden=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   CFLAGS=$ax_check_save_flags
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fvisibility_hidden" >&5
-$as_echo "$ax_cv_check_cflags___fvisibility_hidden" >&6; }
-if test "x$ax_cv_check_cflags___fvisibility_hidden" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fvisibility_hidden" >&5
+printf "%s\n" "$ax_cv_check_cflags___fvisibility_hidden" >&6; }
+if test "x$ax_cv_check_cflags___fvisibility_hidden" = xyes
+then :
   EXTRACFLAG="-fvisibility=hidden"
-else
+else $as_nop
   :
 fi
 
@@ -24305,7 +26945,7 @@ fi
 
 if test "x$debug" != "xno"; then
 
-$as_echo "#define DEBUGBUILD 1" >>confdefs.h
+printf "%s\n" "#define DEBUGBUILD 1" >>confdefs.h
 
 fi
 
@@ -24316,7 +26956,7 @@ if test "x$threads" != "xyes" ||
    test "x$have_std_future" != "xyes"; then
     enable_threads=no
 
-$as_echo "#define NOTHREADS 1" >>confdefs.h
+printf "%s\n" "#define NOTHREADS 1" >>confdefs.h
 
 fi
 
@@ -24333,7 +26973,7 @@ fi
 
 
 
-ac_config_files="$ac_config_files Makefile lib/Makefile lib/libnghttp2.pc lib/includes/Makefile lib/includes/nghttp2/nghttp2ver.h tests/Makefile tests/testdata/Makefile third-party/Makefile src/Makefile src/includes/Makefile src/libnghttp2_asio.pc examples/Makefile python/Makefile python/setup.py integration-tests/Makefile integration-tests/config.go integration-tests/setenv doc/Makefile doc/conf.py doc/index.rst doc/package_README.rst doc/tutorial-client.rst doc/tutorial-server.rst doc/tutorial-hpack.rst doc/nghttpx-howto.rst doc/h2load-howto.rst doc/libnghttp2_asio.rst doc/python-apiref.rst doc/building-android-binary.rst doc/nghttp2.h.rst doc/nghttp2ver.h.rst doc/asio_http2.h.rst doc/asio_http2_server.h.rst doc/asio_http2_client.h.rst doc/contribute.rst contrib/Makefile script/Makefile"
+ac_config_files="$ac_config_files Makefile lib/Makefile lib/libnghttp2.pc lib/includes/Makefile lib/includes/nghttp2/nghttp2ver.h tests/Makefile tests/testdata/Makefile third-party/Makefile src/Makefile src/includes/Makefile src/libnghttp2_asio.pc bpf/Makefile examples/Makefile python/Makefile python/setup.py integration-tests/Makefile integration-tests/config.go integration-tests/setenv doc/Makefile doc/conf.py doc/index.rst doc/package_README.rst doc/tutorial-client.rst doc/tutorial-server.rst doc/tutorial-hpack.rst doc/nghttpx-howto.rst doc/h2load-howto.rst doc/libnghttp2_asio.rst doc/python-apiref.rst doc/building-android-binary.rst doc/nghttp2.h.rst doc/nghttp2ver.h.rst doc/asio_http2.h.rst doc/asio_http2_server.h.rst doc/asio_http2_client.h.rst doc/contribute.rst contrib/Makefile script/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -24362,8 +27002,8 @@ _ACEOF
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
@@ -24393,15 +27033,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      /^ac_cv_env_/b end
      t clear
      :clear
-     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
      t end
      s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
     if test "x$cache_file" != "x/dev/null"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
       if test ! -f "$cache_file" || test -h "$cache_file"; then
        cat confcache >"$cache_file"
       else
@@ -24415,8 +27055,8 @@ $as_echo "$as_me: updating cache $cache_file" >&6;}
       fi
     fi
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
   fi
 fi
 rm -f confcache
@@ -24433,7 +27073,7 @@ U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
   # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
   #    will be set to the directory where LIBOBJS objects are built.
   as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
@@ -24444,14 +27084,14 @@ LIBOBJS=$ac_libobjs
 LTLIBOBJS=$ac_ltlibobjs
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
-$as_echo_n "checking that generated files are newer than configure... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+printf %s "checking that generated files are newer than configure... " >&6; }
    if test -n "$am_sleep_pid"; then
      # Hide warnings about reused PIDs.
      wait $am_sleep_pid 2>/dev/null
    fi
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
-$as_echo "done" >&6; }
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5
+printf "%s\n" "done" >&6; }
 if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
   as_fn_error $? "conditional \"AMDEP\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -24476,6 +27116,10 @@ if test -z "${HAVE_CUNIT_TRUE}" && test -z "${HAVE_CUNIT_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_CUNIT\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${HAVE_LIBBPF_TRUE}" && test -z "${HAVE_LIBBPF_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_LIBBPF\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${HAVE_LIBXML2_TRUE}" && test -z "${HAVE_LIBXML2_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_LIBXML2\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -24484,6 +27128,10 @@ if test -z "${ENABLE_APP_TRUE}" && test -z "${ENABLE_APP_FALSE}"; then
   as_fn_error $? "conditional \"ENABLE_APP\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${ENABLE_HTTP3_TRUE}" && test -z "${ENABLE_HTTP3_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_HTTP3\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${ENABLE_HPACK_TOOLS_TRUE}" && test -z "${ENABLE_HPACK_TOOLS_FALSE}"; then
   as_fn_error $? "conditional \"ENABLE_HPACK_TOOLS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -24530,8 +27178,8 @@ fi
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
 as_write_fail=0
 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
 #! $SHELL
@@ -24554,14 +27202,16 @@ cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
-else
+else $as_nop
   case `(set -o) 2>/dev/null` in #(
   *posix*) :
     set -o posix ;; #(
@@ -24571,46 +27221,46 @@ esac
 fi
 
 
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
 as_nl='
 '
 export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-       expr "X$arg" : "X\\(.*\\)$as_nl";
-       arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
+IFS=" ""       $as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
 
 # The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
+if ${PATH_SEPARATOR+false} :; then
   PATH_SEPARATOR=:
   (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
     (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
@@ -24619,13 +27269,6 @@ if test "${PATH_SEPARATOR+set}" != set; then
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""       $as_nl"
-
 # Find who we are.  Look in the path if we contain no directory separator.
 as_myself=
 case $0 in #((
@@ -24634,8 +27277,12 @@ case $0 in #((
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
   done
 IFS=$as_save_IFS
 
@@ -24647,30 +27294,10 @@ if test "x$as_myself" = x; then
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
   exit 1
 fi
 
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 
 # as_fn_error STATUS ERROR [LINENO LOG_FD]
@@ -24683,13 +27310,14 @@ as_fn_error ()
   as_status=$1; test $as_status -eq 0 && as_status=1
   if test "$4"; then
     as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $2" >&2
+  printf "%s\n" "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
 
+
 # as_fn_set_status STATUS
 # -----------------------
 # Set $? to STATUS, without forking.
@@ -24716,18 +27344,20 @@ as_fn_unset ()
   { eval $1=; unset $1;}
 }
 as_unset=as_fn_unset
+
 # as_fn_append VAR VALUE
 # ----------------------
 # Append the text in VALUE to the end of the definition contained in VAR. Take
 # advantage of any shell optimizations that allow amortized linear growth over
 # repeated appends, instead of the typical quadratic growth present in naive
 # implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
   eval 'as_fn_append ()
   {
     eval $1+=\$2
   }'
-else
+else $as_nop
   as_fn_append ()
   {
     eval $1=\$$1\$2
@@ -24739,12 +27369,13 @@ fi # as_fn_append
 # Perform arithmetic evaluation on the ARGs, and store the result in the
 # global $as_val. Take advantage of shells that can avoid forks. The arguments
 # must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
   eval 'as_fn_arith ()
   {
     as_val=$(( $* ))
   }'
-else
+else $as_nop
   as_fn_arith ()
   {
     as_val=`expr "$@" || test $? -eq 1`
@@ -24775,7 +27406,7 @@ as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         X"$0" : 'X\(//\)$' \| \
         X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
+printf "%s\n" X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
            s//\1/
            q
@@ -24797,6 +27428,10 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS
 as_cr_digits='0123456789'
 as_cr_alnum=$as_cr_Letters$as_cr_digits
 
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
 ECHO_C= ECHO_N= ECHO_T=
 case `echo -n x` in #(((((
 -n*)
@@ -24810,6 +27445,12 @@ case `echo -n x` in #(((((
   ECHO_N='-n';;
 esac
 
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
@@ -24851,7 +27492,7 @@ as_fn_mkdir_p ()
     as_dirs=
     while :; do
       case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
       *) as_qdir=$as_dir;;
       esac
       as_dirs="'$as_qdir' $as_dirs"
@@ -24860,7 +27501,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$as_dir" : 'X\(//\)[^/]' \| \
         X"$as_dir" : 'X\(//\)$' \| \
         X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
+printf "%s\n" X"$as_dir" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -24922,8 +27563,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by nghttp2 $as_me 1.41.0, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
+This file was extended by nghttp2 $as_me 1.46.0, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -24985,14 +27626,16 @@ $config_commands
 Report bugs to <t-tujikawa@users.sourceforge.net>."
 
 _ACEOF
+ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
+ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-nghttp2 config.status 1.41.0
-configured by $0, generated by GNU Autoconf 2.69,
+nghttp2 config.status 1.46.0
+configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
   --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    $as_echo "$ac_cs_version"; exit ;;
+    printf "%s\n" "$ac_cs_version"; exit ;;
   --config | --confi | --conf | --con | --co | --c )
-    $as_echo "$ac_cs_config"; exit ;;
+    printf "%s\n" "$ac_cs_config"; exit ;;
   --debug | --debu | --deb | --de | --d | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
     case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
     '') as_fn_error $? "missing file argument" ;;
     esac
     as_fn_append CONFIG_FILES " '$ac_optarg'"
@@ -25048,7 +27691,7 @@ do
   --header | --heade | --head | --hea )
     $ac_shift
     case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     as_fn_append CONFIG_HEADERS " '$ac_optarg'"
     ac_need_defaults=false;;
@@ -25057,7 +27700,7 @@ do
     as_fn_error $? "ambiguous option: \`$1'
 Try \`$0 --help' for more information.";;
   --help | --hel | -h )
-    $as_echo "$ac_cs_usage"; exit ;;
+    printf "%s\n" "$ac_cs_usage"; exit ;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
@@ -25085,7 +27728,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 if \$ac_cs_recheck; then
   set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
   shift
-  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
   CONFIG_SHELL='$SHELL'
   export CONFIG_SHELL
   exec "\$@"
@@ -25099,7 +27742,7 @@ exec 5>>config.log
   sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
 ## Running $as_me. ##
 _ASBOX
-  $as_echo "$ac_log"
+  printf "%s\n" "$ac_log"
 } >&5
 
 _ACEOF
@@ -25512,6 +28155,7 @@ do
     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
     "src/includes/Makefile") CONFIG_FILES="$CONFIG_FILES src/includes/Makefile" ;;
     "src/libnghttp2_asio.pc") CONFIG_FILES="$CONFIG_FILES src/libnghttp2_asio.pc" ;;
+    "bpf/Makefile") CONFIG_FILES="$CONFIG_FILES bpf/Makefile" ;;
     "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
     "python/Makefile") CONFIG_FILES="$CONFIG_FILES python/Makefile" ;;
     "python/setup.py") CONFIG_FILES="$CONFIG_FILES python/setup.py" ;;
@@ -25549,9 +28193,9 @@ done
 # We use the long form for the default assignment because of an extremely
 # bizarre bug on SunOS 4.1.3.
 if $ac_need_defaults; then
-  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
-  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
-  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+  test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files
+  test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers
+  test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands
 fi
 
 # Have a temporary directory for convenience.  Make it in the build tree
@@ -25887,7 +28531,7 @@ do
           esac ||
           as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
-      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
       as_fn_append ac_file_inputs " '$ac_f'"
     done
 
     # use $as_me), people would be surprised to read:
     #    /* config.h.  Generated by config.status.  */
     configure_input='Generated from '`
-         $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+         printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
        `' by configure.'
     if test x"$ac_file" != x-; then
       configure_input="$ac_file.  $configure_input"
-      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+printf "%s\n" "$as_me: creating $ac_file" >&6;}
     fi
     # Neutralize special characters interpreted by sed in replacement strings.
     case $configure_input in #(
     *\&* | *\|* | *\\* )
-       ac_sed_conf_input=`$as_echo "$configure_input" |
+       ac_sed_conf_input=`printf "%s\n" "$configure_input" |
        sed 's/[\\\\&|]/\\\\&/g'`;; #(
     *) ac_sed_conf_input=$configure_input;;
     esac
@@ -25922,7 +28566,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$ac_file" : 'X\(//\)[^/]' \| \
         X"$ac_file" : 'X\(//\)$' \| \
         X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
+printf "%s\n" X"$ac_file" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -25946,9 +28590,9 @@ $as_echo X"$ac_file" |
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -26010,8 +28654,8 @@ ac_sed_dataroot='
 case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
 *datarootdir*) ac_datarootdir_seen=yes;;
 *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
   ac_datarootdir_hack='
@@ -26055,9 +28699,9 @@ test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
   { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
   { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' \
       "$ac_tmp/out"`; test -z "$ac_out"; } &&
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&5
-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&2;}
 
   rm -f "$ac_tmp/stdin"
@@ -26073,20 +28717,20 @@ which seems to be undefined.  Please make sure it is defined" >&2;}
   #
   if test x"$ac_file" != x-; then
     {
-      $as_echo "/* $configure_input  */" \
+      printf "%s\n" "/* $configure_input  */" >&1 \
       && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
     } >"$ac_tmp/config.h" \
       || as_fn_error $? "could not create $ac_file" "$LINENO" 5
     if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+printf "%s\n" "$as_me: $ac_file is unchanged" >&6;}
     else
       rm -f "$ac_file"
       mv "$ac_tmp/config.h" "$ac_file" \
        || as_fn_error $? "could not create $ac_file" "$LINENO" 5
     fi
   else
-    $as_echo "/* $configure_input  */" \
+    printf "%s\n" "/* $configure_input  */" >&1 \
       && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
       || as_fn_error $? "could not create -" "$LINENO" 5
   fi
@@ -26106,7 +28750,7 @@ $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$_am_arg" : 'X\(//\)[^/]' \| \
         X"$_am_arg" : 'X\(//\)$' \| \
         X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$_am_arg" |
+printf "%s\n" X"$_am_arg" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -26126,8 +28770,8 @@ $as_echo X"$_am_arg" |
          s/.*/./; q'`/stamp-h$_am_stamp_count
  ;;
 
-  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
-$as_echo "$as_me: executing $ac_file commands" >&6;}
+  :C)  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+printf "%s\n" "$as_me: executing $ac_file commands" >&6;}
  ;;
   esac
 
@@ -26674,6 +29318,7 @@ _LT_EOF
   esac
 
 
+
 ltmain=$ac_aux_dir/ltmain.sh
 
 
@@ -26862,7 +29507,7 @@ esac
   for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
+    am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'`
     # Check whether this is an Automake generated Makefile which includes
     # dependency-tracking related rules and includes.
     # Grep'ing the whole file directly is not great: AIX grep has a line
@@ -26874,7 +29519,7 @@ $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$am_mf" : 'X\(//\)[^/]' \| \
         X"$am_mf" : 'X\(//\)$' \| \
         X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$am_mf" |
+printf "%s\n" X"$am_mf" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -26896,7 +29541,7 @@ $as_echo X"$am_mf" |
 $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
         X"$am_mf" : 'X\(//\)$' \| \
         X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$am_mf" |
+printf "%s\n" X/"$am_mf" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
            s//\1/
            q
@@ -26921,10 +29566,12 @@ $as_echo X/"$am_mf" |
    (exit $ac_status); } || am_rc=$?
   done
   if test $am_rc -ne 0; then
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE=\"gmake\" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).
 See \`config.log' for more details" "$LINENO" 5; }
@@ -26970,12 +29617,12 @@ if test "$no_create" != yes; then
   $ac_cs_success || as_fn_exit 1
 fi
 if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: summary of build options:
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: summary of build options:
 
     Package version: ${VERSION}
     Library version: $LT_CURRENT:$LT_REVISION:$LT_AGE
       WARNCXXFLAGS:   ${WARNCXXFLAGS}
       CXX1XCXXFLAGS:  ${CXX1XCXXFLAGS}
       EXTRACFLAG:     ${EXTRACFLAG}
+      BPFCFLAGS:      ${BPFCFLAGS}
+      EXTRABPFCFLAGS: ${EXTRABPFCFLAGS}
       LIBS:           ${LIBS}
+      DEFS:           ${DEFS}
+      EXTRA_DEFS:     ${EXTRA_DEFS}
     Library:
       Shared:         ${enable_shared}
       Static:         ${enable_static}
+    Libtool:
+      LIBTOOL_LDFLAGS: ${LIBTOOL_LDFLAGS}
     Python:
       Python:         ${PYTHON}
       PYTHON_VERSION: ${PYTHON_VERSION}
       pyexecdir:      ${pyexecdir}
-      Python-dev:     ${have_python_dev}
       PYTHON_CPPFLAGS:${PYTHON_CPPFLAGS}
-      PYTHON_LDFLAGS: ${PYTHON_LDFLAGS}
+      PYTHON_LIBS:    ${PYTHON_LIBS}
       Cython:         ${CYTHON}
     Test:
       CUnit:          ${have_cunit} (CFLAGS='${CUNIT_CFLAGS}' LIBS='${CUNIT_LIBS}')
       Libxml2:        ${have_libxml2} (CFLAGS='${LIBXML2_CFLAGS}' LIBS='${LIBXML2_LIBS}')
       Libev:          ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}')
       Libc-ares:      ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}')
+      libngtcp2:      ${have_libngtcp2} (CFLAGS='${LIBNGTCP2_CFLAGS}' LIBS='${LIBNGTCP2_LIBS}')
+      libngtcp2_crypto_openssl: ${have_libngtcp2_crypto_openssl} (CFLAGS='${LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_OPENSSL_LIBS}')
+      libngtcp2_crypto_boringssl: ${have_libngtcp2_crypto_boringssl} (CFLAGS='${LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_BORINGSSL_LIBS}')
+      libnghttp3:     ${have_libnghttp3} (CFLAGS='${LIBNGHTTP3_CFLAGS}' LIBS='${LIBNGHTTP3_LIBS}')
+      libbpf:         ${have_libbpf} (CFLAGS='${LIBBPF_CFLAGS}' LIBS='${LIBBPF_LIBS}')
       Libevent(SSL):  ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')
       Jansson:        ${have_jansson} (CFLAGS='${JANSSON_CFLAGS}' LIBS='${JANSSON_LIBS}')
-      Jemalloc:       ${have_jemalloc} (LIBS='${JEMALLOC_LIBS}')
+      Jemalloc:       ${have_jemalloc} (CFLAGS='${JEMALLOC_CFLAGS}' LIBS='${JEMALLOC_LIBS}')
       Zlib:           ${have_zlib} (CFLAGS='${ZLIB_CFLAGS}' LIBS='${ZLIB_LIBS}')
       Systemd:        ${have_libsystemd} (CFLAGS='${SYSTEMD_CFLAGS}' LIBS='${SYSTEMD_LIBS}')
       Boost CPPFLAGS: ${BOOST_CPPFLAGS}
@@ -27038,8 +29695,9 @@ fi
       Examples:       ${enable_examples}
       Python bindings:${enable_python_bindings}
       Threading:      ${enable_threads}
+      HTTP/3 (EXPERIMENTAL): ${enable_http3}
 " >&5
-$as_echo "$as_me: summary of build options:
+printf "%s\n" "$as_me: summary of build options:
 
     Package version: ${VERSION}
     Library version: $LT_CURRENT:$LT_REVISION:$LT_AGE
@@ -27061,17 +29719,22 @@ $as_echo "$as_me: summary of build options:
       WARNCXXFLAGS:   ${WARNCXXFLAGS}
       CXX1XCXXFLAGS:  ${CXX1XCXXFLAGS}
       EXTRACFLAG:     ${EXTRACFLAG}
+      BPFCFLAGS:      ${BPFCFLAGS}
+      EXTRABPFCFLAGS: ${EXTRABPFCFLAGS}
       LIBS:           ${LIBS}
+      DEFS:           ${DEFS}
+      EXTRA_DEFS:     ${EXTRA_DEFS}
     Library:
       Shared:         ${enable_shared}
       Static:         ${enable_static}
+    Libtool:
+      LIBTOOL_LDFLAGS: ${LIBTOOL_LDFLAGS}
     Python:
       Python:         ${PYTHON}
       PYTHON_VERSION: ${PYTHON_VERSION}
       pyexecdir:      ${pyexecdir}
-      Python-dev:     ${have_python_dev}
       PYTHON_CPPFLAGS:${PYTHON_CPPFLAGS}
-      PYTHON_LDFLAGS: ${PYTHON_LDFLAGS}
+      PYTHON_LIBS:    ${PYTHON_LIBS}
       Cython:         ${CYTHON}
     Test:
       CUnit:          ${have_cunit} (CFLAGS='${CUNIT_CFLAGS}' LIBS='${CUNIT_LIBS}')
@@ -27081,9 +29744,14 @@ $as_echo "$as_me: summary of build options:
       Libxml2:        ${have_libxml2} (CFLAGS='${LIBXML2_CFLAGS}' LIBS='${LIBXML2_LIBS}')
       Libev:          ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}')
       Libc-ares:      ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}')
+      libngtcp2:      ${have_libngtcp2} (CFLAGS='${LIBNGTCP2_CFLAGS}' LIBS='${LIBNGTCP2_LIBS}')
+      libngtcp2_crypto_openssl: ${have_libngtcp2_crypto_openssl} (CFLAGS='${LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_OPENSSL_LIBS}')
+      libngtcp2_crypto_boringssl: ${have_libngtcp2_crypto_boringssl} (CFLAGS='${LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_BORINGSSL_LIBS}')
+      libnghttp3:     ${have_libnghttp3} (CFLAGS='${LIBNGHTTP3_CFLAGS}' LIBS='${LIBNGHTTP3_LIBS}')
+      libbpf:         ${have_libbpf} (CFLAGS='${LIBBPF_CFLAGS}' LIBS='${LIBBPF_LIBS}')
       Libevent(SSL):  ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')
       Jansson:        ${have_jansson} (CFLAGS='${JANSSON_CFLAGS}' LIBS='${JANSSON_LIBS}')
-      Jemalloc:       ${have_jemalloc} (LIBS='${JEMALLOC_LIBS}')
+      Jemalloc:       ${have_jemalloc} (CFLAGS='${JEMALLOC_CFLAGS}' LIBS='${JEMALLOC_LIBS}')
       Zlib:           ${have_zlib} (CFLAGS='${ZLIB_CFLAGS}' LIBS='${ZLIB_LIBS}')
       Systemd:        ${have_libsystemd} (CFLAGS='${SYSTEMD_CFLAGS}' LIBS='${SYSTEMD_LIBS}')
       Boost CPPFLAGS: ${BOOST_CPPFLAGS}
@@ -27102,4 +29770,6 @@ $as_echo "$as_me: summary of build options:
       Examples:       ${enable_examples}
       Python bindings:${enable_python_bindings}
       Threading:      ${enable_threads}
+      HTTP/3 (EXPERIMENTAL): ${enable_http3}
 " >&6;}
+
index 961b78d..bec2aa3 100644 (file)
@@ -22,10 +22,10 @@ dnl OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 dnl WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 dnl Do not change user variables!
-dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
+dnl https://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
 
 AC_PREREQ(2.61)
-AC_INIT([nghttp2], [1.41.0], [t-tujikawa@users.sourceforge.net])
+AC_INIT([nghttp2], [1.46.0], [t-tujikawa@users.sourceforge.net])
 AC_CONFIG_AUX_DIR([.])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS([config.h])
@@ -43,10 +43,10 @@ AM_INIT_AUTOMAKE([subdir-objects])
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
 dnl See versioning rule:
-dnl  http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
-AC_SUBST(LT_CURRENT, 34)
-AC_SUBST(LT_REVISION, 0)
-AC_SUBST(LT_AGE, 20)
+dnl  https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+AC_SUBST(LT_CURRENT, 35)
+AC_SUBST(LT_REVISION, 1)
+AC_SUBST(LT_AGE, 21)
 
 major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
 minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
@@ -107,11 +107,51 @@ AC_ARG_ENABLE([lib-only],
                     [Build libnghttp2 only.  This is a short hand for --disable-app --disable-examples --disable-hpack-tools --disable-python-bindings])],
     [request_lib_only=$enableval], [request_lib_only=no])
 
+AC_ARG_ENABLE([http3],
+    [AS_HELP_STRING([--enable-http3],
+                    [(EXPERIMENTAL) Enable HTTP/3.  This requires ngtcp2, nghttp3, and a custom OpenSSL.])],
+    [request_http3=$enableval], [request_http3=no])
+
 AC_ARG_WITH([libxml2],
     [AS_HELP_STRING([--with-libxml2],
                     [Use libxml2 [default=check]])],
     [request_libxml2=$withval], [request_libxml2=check])
 
+AC_ARG_WITH([jansson],
+    [AS_HELP_STRING([--with-jansson],
+                    [Use jansson [default=check]])],
+    [request_jansson=$withval], [request_jansson=check])
+
+AC_ARG_WITH([zlib],
+    [AS_HELP_STRING([--with-zlib],
+                    [Use zlib [default=check]])],
+    [request_zlib=$withval], [request_zlib=check])
+
+AC_ARG_WITH([libevent-openssl],
+    [AS_HELP_STRING([--with-libevent-openssl],
+                    [Use libevent_openssl [default=check]])],
+    [request_libevent_openssl=$withval], [request_libevent_openssl=check])
+
+AC_ARG_WITH([libcares],
+    [AS_HELP_STRING([--with-libcares],
+                    [Use libc-ares [default=check]])],
+    [request_libcares=$withval], [request_libcares=check])
+
+AC_ARG_WITH([openssl],
+    [AS_HELP_STRING([--with-openssl],
+                    [Use openssl [default=check]])],
+    [request_openssl=$withval], [request_openssl=check])
+
+AC_ARG_WITH([libev],
+    [AS_HELP_STRING([--with-libev],
+                    [Use libev [default=check]])],
+    [request_libev=$withval], [request_libev=check])
+
+AC_ARG_WITH([cunit],
+    [AS_HELP_STRING([--with-cunit],
+                    [Use cunit [default=check]])],
+    [request_cunit=$withval], [request_cunit=check])
+
 AC_ARG_WITH([jemalloc],
     [AS_HELP_STRING([--with-jemalloc],
                     [Use jemalloc [default=check]])],
@@ -137,9 +177,36 @@ AC_ARG_WITH([cython],
                     [Use cython in given PATH])],
     [cython_path=$withval], [])
 
+AC_ARG_WITH([libngtcp2],
+    [AS_HELP_STRING([--with-libngtcp2],
+                    [Use libngtcp2 [default=check]])],
+    [request_libngtcp2=$withval], [request_libngtcp2=check])
+
+AC_ARG_WITH([libnghttp3],
+    [AS_HELP_STRING([--with-libnghttp3],
+                    [Use libnghttp3 [default=check]])],
+    [request_libnghttp3=$withval], [request_libnghttp3=check])
+
+AC_ARG_WITH([libbpf],
+    [AS_HELP_STRING([--with-libbpf],
+                    [Use libbpf [default=no]])],
+    [request_libbpf=$withval], [request_libbpf=no])
+
 dnl Define variables
 AC_ARG_VAR([CYTHON], [the Cython executable])
 
+AC_ARG_VAR([LIBEV_CFLAGS], [C compiler flags for libev, skipping any checks])
+AC_ARG_VAR([LIBEV_LIBS], [linker flags for libev, skipping any checks])
+
+AC_ARG_VAR([JEMALLOC_CFLAGS],
+           [C compiler flags for jemalloc, skipping any checks])
+AC_ARG_VAR([JEMALLOC_LIBS], [linker flags for jemalloc, skipping any checks])
+
+AC_ARG_VAR([LIBTOOL_LDFLAGS],
+           [libtool specific flags (e.g., -static-libtool-libs)])
+
+AC_ARG_VAR([BPFCFLAGS], [C compiler flags for bpf program])
+
 dnl Checks for programs
 AC_PROG_CC
 AC_PROG_CXX
@@ -151,7 +218,12 @@ AC_PROG_MKDIR_P
 
 PKG_PROG_PKG_CONFIG([0.20])
 
-AM_PATH_PYTHON([2.7],, [:])
+AM_PATH_PYTHON([3.8],, [:])
+
+if test "x$request_python_bindings" = "xyes" &&
+   test "x$PYTHON" = "x:"; then
+  AC_MSG_ERROR([python was requested (enable-python-bindings) but not found])
+fi
 
 if [test "x$request_lib_only" = "xyes"]; then
   request_app=no
@@ -160,8 +232,10 @@ if [test "x$request_lib_only" = "xyes"]; then
   request_python_bindings=no
 fi
 
-if [test "x$request_python_bindings" != "xno"]; then
-  AX_PYTHON_DEVEL([>= '2.7'])
+if test "x$request_python_bindings" != "xno" &&
+   test "x$PYTHON" != "x:"; then
+  # version check is broken
+  AX_PYTHON_DEVEL()
 fi
 
 if test "x${cython_path}" = "x"; then
@@ -200,6 +274,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
 ]],
 [[
 std::vector<std::future<int>> v;
+(void)v;
 ]])],
     [AC_DEFINE([HAVE_STD_FUTURE], [1],
                [Define to 1 if you have the `std::future`.])
@@ -289,11 +364,26 @@ case "$host_os" in
     ;;
 esac
 
+case "${build}" in
+  *-apple-darwin*)
+    EXTRA_DEFS="-D__APPLE_USE_RFC_3542"
+    AC_SUBST([EXTRA_DEFS])
+    ;;
+esac
+
 # zlib
-PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.3], [have_zlib=yes], [have_zlib=no])
+have_zlib=no
+if test "x${request_zlib}" != "xno"; then
+  PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.3], [have_zlib=yes], [have_zlib=no])
+
+  if test "x${have_zlib}" = "xno"; then
+    AC_MSG_NOTICE($ZLIB_PKG_ERRORS)
+  fi
+fi
 
-if test "x${have_zlib}" = "xno"; then
-  AC_MSG_NOTICE($ZLIB_PKG_ERRORS)
+if test "x${request_zlib}" = "xyes" &&
+   test "x${have_zlib}" != "xyes"; then
+  AC_MSG_ERROR([zlib was requested (--with-zlib) but not found])
 fi
 
 # dl: openssl requires libdl when it is statically linked.
@@ -309,82 +399,281 @@ case "${host_os}" in
 esac
 
 # cunit
-PKG_CHECK_MODULES([CUNIT], [cunit >= 2.1], [have_cunit=yes], [have_cunit=no])
-# If pkg-config does not find cunit, check it using AC_CHECK_LIB.  We
-# do this because Debian (Ubuntu) lacks pkg-config file for cunit.
-if test "x${have_cunit}" = "xno"; then
-  AC_MSG_WARN([${CUNIT_PKG_ERRORS}])
-  AC_CHECK_LIB([cunit], [CU_initialize_registry],
-               [have_cunit=yes], [have_cunit=no])
+have_cunit=no
+if test "x${request_cunit}" != "xno"; then
+  PKG_CHECK_MODULES([CUNIT], [cunit >= 2.1], [have_cunit=yes], [have_cunit=no])
+  # If pkg-config does not find cunit, check it using AC_CHECK_LIB.  We
+  # do this because Debian (Ubuntu) lacks pkg-config file for cunit.
+  if test "x${have_cunit}" = "xno"; then
+    AC_MSG_WARN([${CUNIT_PKG_ERRORS}])
+    AC_CHECK_LIB([cunit], [CU_initialize_registry],
+                 [have_cunit=yes], [have_cunit=no])
+    if test "x${have_cunit}" = "xyes"; then
+      CUNIT_LIBS="-lcunit"
+      CUNIT_CFLAGS=""
+      AC_SUBST([CUNIT_LIBS])
+      AC_SUBST([CUNIT_CFLAGS])
+    fi
+  fi
   if test "x${have_cunit}" = "xyes"; then
-    CUNIT_LIBS="-lcunit"
-    CUNIT_CFLAGS=""
-    AC_SUBST([CUNIT_LIBS])
-    AC_SUBST([CUNIT_CFLAGS])
+    # cunit in Mac OS X requires ncurses. Note that in Mac OS X, test
+    # program can be built without -lncurses, but it emits runtime
+    # error.
+    case "${build}" in
+      *-apple-darwin*)
+        CUNIT_LIBS="$CUNIT_LIBS -lncurses"
+        AC_SUBST([CUNIT_LIBS])
+        ;;
+    esac
   fi
 fi
-if test "x${have_cunit}" = "xyes"; then
-  # cunit in Mac OS X requires ncurses. Note that in Mac OS X, test
-  # program can be built without -lncurses, but it emits runtime
-  # error.
-  case "${build}" in
-    *-apple-darwin*)
-      CUNIT_LIBS="$CUNIT_LIBS -lncurses"
-      AC_SUBST([CUNIT_LIBS])
-      ;;
-  esac
+
+if test "x${request_cunit}" = "xyes" &&
+   test "x${have_cunit}" != "xyes"; then
+  AC_MSG_ERROR([cunit was requested (--with-cunit) but not found])
 fi
 
 AM_CONDITIONAL([HAVE_CUNIT], [ test "x${have_cunit}" = "xyes" ])
 
 # libev (for src)
-# libev does not have pkg-config file.  Check it in an old way.
-save_LIBS=$LIBS
-# android requires -lm for floor
-AC_CHECK_LIB([ev], [ev_time], [have_libev=yes], [have_libev=no], [-lm])
-if test "x${have_libev}" = "xyes"; then
-  AC_CHECK_HEADER([ev.h], [have_libev=yes], [have_libev=no])
-  if test "x${have_libev}" = "xyes"; then
-    LIBEV_LIBS=-lev
-    LIBEV_CFLAGS=
-    AC_SUBST([LIBEV_LIBS])
-    AC_SUBST([LIBEV_CFLAGS])
+have_libev=no
+if test "x${request_libev}" != "xno"; then
+  if test "x${LIBEV_LIBS}" = "x" && test "x${LIBEV_CFLAGS}" = "x"; then
+    # libev does not have pkg-config file.  Check it in an old way.
+    save_LIBS=$LIBS
+    # android requires -lm for floor
+   AC_CHECK_LIB([ev], [ev_time], [have_libev=yes], [have_libev=no], [-lm])
+   if test "x${have_libev}" = "xyes"; then
+      AC_CHECK_HEADER([ev.h], [have_libev=yes], [have_libev=no])
+      if test "x${have_libev}" = "xyes"; then
+        LIBEV_LIBS=-lev
+        LIBEV_CFLAGS=
+      fi
+    fi
+    LIBS=$save_LIBS
+  else
+    have_libev=yes
   fi
 fi
-LIBS=$save_LIBS
+
+if test "x${request_libev}" = "xyes" &&
+   test "x${have_libev}" != "xyes"; then
+  AC_MSG_ERROR([libev was requested (--with-libev) but not found])
+fi
 
 # openssl (for src)
-PKG_CHECK_MODULES([OPENSSL], [openssl >= 1.0.1],
-                  [have_openssl=yes], [have_openssl=no])
-if test "x${have_openssl}" = "xno"; then
-  AC_MSG_NOTICE($OPENSSL_PKG_ERRORS)
+have_openssl=no
+if test "x${request_openssl}" != "xno"; then
+  PKG_CHECK_MODULES([OPENSSL], [openssl >= 1.0.1],
+                    [have_openssl=yes], [have_openssl=no])
+  if test "x${have_openssl}" = "xno"; then
+    AC_MSG_NOTICE($OPENSSL_PKG_ERRORS)
+  else
+    save_CFLAGS="$CFLAGS"
+    save_LIBS="$LIBS"
+    CFLAGS="$OPENSSL_CFLAGS $CFLAGS"
+    LIBS="$OPENSSL_LIBS $LIBS"
+
+    # quictls/openssl has SSL_is_quic.
+    have_ssl_is_quic=no
+    AC_MSG_CHECKING([for SSL_is_quic])
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+      #include <openssl/ssl.h>
+    ]], [[
+      SSL *ssl = NULL;
+      SSL_is_quic(ssl);
+    ]])],
+    [AC_MSG_RESULT([yes]); have_ssl_is_quic=yes],
+    [AC_MSG_RESULT([no]); have_ssl_is_quic=no])
+
+    # boringssl has SSL_set_quic_early_data_context.
+    AC_MSG_CHECKING([for SSL_set_quic_early_data_context])
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+      #include <openssl/ssl.h>
+    ]], [[
+      SSL *ssl = NULL;
+      SSL_set_quic_early_data_context(ssl, NULL, 0);
+    ]])],
+    [AC_MSG_RESULT([yes]); have_boringssl_quic=yes],
+    [AC_MSG_RESULT([no]); have_boringssl_quic=no])
+
+    CFLAGS="$save_CFLAGS"
+    LIBS="$save_LIBS"
+  fi
+fi
+
+if test "x${request_openssl}" = "xyes" &&
+   test "x${have_openssl}" != "xyes"; then
+  AC_MSG_ERROR([openssl was requested (--with-openssl) but not found])
 fi
 
 # c-ares (for src)
-PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.7.5], [have_libcares=yes],
-                  [have_libcares=no])
-if test "x${have_libcares}" = "xno"; then
-  AC_MSG_NOTICE($LIBCARES_PKG_ERRORS)
+have_libcares=no
+if test "x${request_libcares}" != "xno"; then
+  PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.7.5], [have_libcares=yes],
+                    [have_libcares=no])
+  if test "x${have_libcares}" = "xno"; then
+    AC_MSG_NOTICE($LIBCARES_PKG_ERRORS)
+  fi
+fi
+
+if test "x${request_libcares}" = "xyes" &&
+   test "x${have_libcares}" != "xyes"; then
+  AC_MSG_ERROR([libcares was requested (--with-libcares) but not found])
+fi
+
+# ngtcp2 (for src)
+have_libngtcp2=no
+if test "x${request_libngtcp2}" != "xno"; then
+  PKG_CHECK_MODULES([LIBNGTCP2], [libngtcp2 >= 0.0.0], [have_libngtcp2=yes],
+                    [have_libngtcp2=no])
+  if test "x${have_libngtcp2}" = "xno"; then
+    AC_MSG_NOTICE($LIBNGTCP2_PKG_ERRORS)
+  fi
+fi
+
+if test "x${request_libngtcp2}" = "xyes" &&
+   test "x${have_libngtcp2}" != "xyes"; then
+  AC_MSG_ERROR([libngtcp2 was requested (--with-libngtcp2) but not found])
+fi
+
+# ngtcp2_crypto_openssl (for src)
+have_libngtcp2_crypto_openssl=no
+if test "x${have_ssl_is_quic}" = "xyes" &&
+   test "x${request_libngtcp2}" != "xno"; then
+  PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_OPENSSL],
+                    [libngtcp2_crypto_openssl >= 0.0.0],
+                    [have_libngtcp2_crypto_openssl=yes],
+                    [have_libngtcp2_crypto_openssl=no])
+  if test "x${have_libngtcp2_crypto_openssl}" = "xno"; then
+    AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_OPENSSL_PKG_ERRORS)
+  else
+    AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_OPENSSL], [1],
+              [Define to 1 if you have `libngtcp2_crypto_openssl` library.])
+  fi
 fi
 
+if test "x${have_ssl_is_quic}" = "xyes" &&
+   test "x${request_libngtcp2}" = "xyes" &&
+   test "x${have_libngtcp2_crypto_openssl}" != "xyes"; then
+  AC_MSG_ERROR([libngtcp2_crypto_openssl was requested (--with-libngtcp2) but not found])
+fi
+
+# ngtcp2_crypto_boringssl (for src)
+have_libngtcp2_crypto_boringssl=no
+if test "x${have_boringssl_quic}" = "xyes" &&
+   test "x${request_libngtcp2}" != "xno"; then
+  PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_BORINGSSL],
+                    [libngtcp2_crypto_boringssl >= 0.0.0],
+                    [have_libngtcp2_crypto_boringssl=yes],
+                    [have_libngtcp2_crypto_boringssl=no])
+  if test "x${have_libngtcp2_crypto_boringssl}" = "xno"; then
+    AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_BORINGSSL_PKG_ERRORS)
+  else
+    AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_BORINGSSL], [1],
+              [Define to 1 if you have `libngtcp2_crypto_boringssl` library.])
+  fi
+fi
+
+if test "x${have_boringssl_quic}" = "xyes" &&
+   test "x${request_libngtcp2}" = "xyes" &&
+   test "x${have_libngtcp2_crypto_boringssl}" != "xyes"; then
+  AC_MSG_ERROR([libngtcp2_crypto_boringssl was requested (--with-libngtcp2) but not found])
+fi
+
+# nghttp3 (for src)
+have_libnghttp3=no
+if test "x${request_libnghttp3}" != "xno"; then
+  PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 0.0.0], [have_libnghttp3=yes],
+                    [have_libnghttp3=no])
+  if test "x${have_libnghttp3}" = "xno"; then
+    AC_MSG_NOTICE($LIBNGHTTP3_PKG_ERRORS)
+  fi
+fi
+
+if test "x${request_libnghttp3}" = "xyes" &&
+   test "x${have_libnghttp3}" != "xyes"; then
+  AC_MSG_ERROR([libnghttp3 was requested (--with-libnghttp3) but not found])
+fi
+
+# libbpf (for src)
+have_libbpf=no
+if test "x${request_libbpf}" != "xno"; then
+  PKG_CHECK_MODULES([LIBBPF], [libbpf >= 0.4.0], [have_libbpf=yes],
+                    [have_libbpf=no])
+  if test "x${have_libbpf}" = "xyes"; then
+    AC_DEFINE([HAVE_LIBBPF], [1], [Define to 1 if you have `libbpf` library.])
+    if test "x${BPFCFLAGS}" = "x"; then
+      BPFCFLAGS="-Wall -O2 -g"
+    fi
+    # Add the include path for Debian
+    EXTRABPFCFLAGS="-I/usr/include/$host_cpu-$host_os"
+    AC_SUBST([EXTRABPFCFLAGS])
+
+    AC_MSG_CHECKING([whether enum bpf_stats_type is defined in linux/bpf.h])
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+    [[
+    #include <linux/bpf.h>
+    ]],
+    [[
+    enum bpf_stats_type foo;
+    (void)foo;
+    ]])],
+    [have_bpf_stats_type=yes],
+    [have_bpf_stats_type=no])
+
+    if test "x${have_bpf_stats_type}" = "xyes"; then
+      AC_MSG_RESULT([yes])
+      AC_DEFINE([HAVE_BPF_STATS_TYPE], [1],
+                [Define to 1 if you have enum bpf_stats_type in linux/bpf.h.])
+    else
+      AC_MSG_RESULT([no])
+    fi
+  else
+    AC_MSG_NOTICE($LIBBPF_PKG_ERRORS)
+  fi
+fi
+
+if test "x${request_libbpf}" = "xyes" &&
+   test "x${have_libbpf}" != "xyes"; then
+  AC_MSG_ERROR([libbpf was requested (--with-libbpf) but not found])
+fi
+
+AM_CONDITIONAL([HAVE_LIBBPF], [ test "x${have_libbpf}" = "xyes" ])
+
 # libevent_openssl (for examples)
 # 2.0.8 is required because we use evconnlistener_set_error_cb()
-PKG_CHECK_MODULES([LIBEVENT_OPENSSL], [libevent_openssl >= 2.0.8],
-                  [have_libevent_openssl=yes], [have_libevent_openssl=no])
-if test "x${have_libevent_openssl}" = "xno"; then
-  AC_MSG_NOTICE($LIBEVENT_OPENSSL_PKG_ERRORS)
+have_libevent_openssl=no
+if test "x${request_libevent_openssl}" != "xno"; then
+  PKG_CHECK_MODULES([LIBEVENT_OPENSSL], [libevent_openssl >= 2.0.8],
+                    [have_libevent_openssl=yes], [have_libevent_openssl=no])
+  if test "x${have_libevent_openssl}" = "xno"; then
+    AC_MSG_NOTICE($LIBEVENT_OPENSSL_PKG_ERRORS)
+  fi
+fi
+
+if test "x${request_libevent_openssl}" = "xyes" &&
+   test "x${have_libevent_openssl}" != "xyes"; then
+  AC_MSG_ERROR([libevent_openssl was requested (--with-libevent) but not found])
 fi
 
 # jansson (for src/nghttp, src/deflatehd and src/inflatehd)
-PKG_CHECK_MODULES([JANSSON], [jansson >= 2.5],
-                  [have_jansson=yes], [have_jansson=no])
-if test "x${have_jansson}" = "xyes"; then
-  AC_DEFINE([HAVE_JANSSON], [1],
-            [Define to 1 if you have `libjansson` library.])
-else
-  AC_MSG_NOTICE($JANSSON_PKG_ERRORS)
+have_jansson=no
+if test "x${request_jansson}" != "xno"; then
+  PKG_CHECK_MODULES([JANSSON], [jansson >= 2.5],
+                    [have_jansson=yes], [have_jansson=no])
+  if test "x${have_jansson}" = "xyes"; then
+    AC_DEFINE([HAVE_JANSSON], [1],
+              [Define to 1 if you have `libjansson` library.])
+  else
+    AC_MSG_NOTICE($JANSSON_PKG_ERRORS)
+  fi
 fi
 
+if test "x${request_jansson}" = "xyes" &&
+   test "x${have_jansson}" != "xyes"; then
+  AC_MSG_ERROR([jansson was requested (--with-jansson) but not found])
+fi
 
 #  libsystemd (for src/nghttpx)
 have_libsystemd=no
@@ -405,12 +694,15 @@ if test "x${request_systemd}" = "xyes" &&
 fi
 
 # libxml2 (for src/nghttp)
-PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.6.26],
-                  [have_libxml2=yes], [have_libxml2=no])
-if test "x${have_libxml2}" = "xyes"; then
-  AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have `libxml2` library.])
-else
-  AC_MSG_NOTICE($LIBXML2_PKG_ERRORS)
+have_libxml2=no
+if test "x${request_libxml2}" != "xno"; then
+  PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.6.26],
+                    [have_libxml2=yes], [have_libxml2=no])
+  if test "x${have_libxml2}" = "xyes"; then
+    AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have `libxml2` library.])
+  else
+    AC_MSG_NOTICE($LIBXML2_PKG_ERRORS)
+  fi
 fi
 
 if test "x${request_libxml2}" = "xyes" &&
@@ -423,28 +715,31 @@ AM_CONDITIONAL([HAVE_LIBXML2], [ test "x${have_libxml2}" = "xyes" ])
 # jemalloc
 have_jemalloc=no
 if test "x${request_jemalloc}" != "xno"; then
-  save_LIBS=$LIBS
-  AC_SEARCH_LIBS([malloc_stats_print], [jemalloc], [have_jemalloc=yes], [],
-                 [$PTHREAD_LDFLAGS])
-
-  if test "x${have_jemalloc}" = "xyes"; then
-    jemalloc_libs=${ac_cv_search_malloc_stats_print}
-  else
-    # On Darwin, malloc_stats_print is je_malloc_stats_print
-    AC_SEARCH_LIBS([je_malloc_stats_print], [jemalloc], [have_jemalloc=yes], [],
+  if test "x${JEMALLOC_LIBS}" = "x" && test "x${JEMALLOC_CFLAGS}" = "x"; then
+    save_LIBS=$LIBS
+    AC_SEARCH_LIBS([malloc_stats_print], [jemalloc], [have_jemalloc=yes], [],
                    [$PTHREAD_LDFLAGS])
 
     if test "x${have_jemalloc}" = "xyes"; then
-      jemalloc_libs=${ac_cv_search_je_malloc_stats_print}
+      jemalloc_libs=${ac_cv_search_malloc_stats_print}
+    else
+      # On Darwin, malloc_stats_print is je_malloc_stats_print
+      AC_SEARCH_LIBS([je_malloc_stats_print], [jemalloc], [have_jemalloc=yes], [],
+                     [$PTHREAD_LDFLAGS])
+
+      if test "x${have_jemalloc}" = "xyes"; then
+        jemalloc_libs=${ac_cv_search_je_malloc_stats_print}
+      fi
     fi
-  fi
 
-  LIBS=$save_LIBS
+    LIBS=$save_LIBS
 
-  if test "x${have_jemalloc}" = "xyes" &&
-     test "x${jemalloc_libs}" != "xnone required"; then
-    JEMALLOC_LIBS=${jemalloc_libs}
-    AC_SUBST([JEMALLOC_LIBS])
+    if test "x${have_jemalloc}" = "xyes" &&
+       test "x${jemalloc_libs}" != "xnone required"; then
+      JEMALLOC_LIBS=${jemalloc_libs}
+    fi
+  else
+    have_jemalloc=yes
   fi
 fi
 
@@ -490,6 +785,26 @@ fi
 
 AM_CONDITIONAL([ENABLE_APP], [ test "x${enable_app}" = "xyes" ])
 
+# Check HTTP/3 support
+enable_http3=no
+if test "x${request_http3}" != "xno" &&
+   (test "x${have_ssl_is_quic}" = "xyes" ||
+    test "x${have_boringssl_quic}" = "xyes") &&
+   test "x${have_libngtcp2}" = "xyes" &&
+   (test "x${have_libngtcp2_crypto_openssl}" = "xyes" ||
+    test "x${have_libngtcp2_crypto_boringssl}" = "xyes") &&
+   test "x${have_libnghttp3}" = "xyes"; then
+  enable_http3=yes
+  AC_DEFINE([ENABLE_HTTP3], [1], [Define to 1 if HTTP/3 is enabled.])
+fi
+
+if test "x${request_http3}" = "xyes" &&
+   test "x${enable_http3}" != "xyes"; then
+  AC_MSG_ERROR([HTTP/3 was requested (--enable-http3) but dependencies are not met.])
+fi
+
+AM_CONDITIONAL([ENABLE_HTTP3], [ test "x${enable_http3}" = "xyes" ])
+
 enable_hpack_tools=no
 # HPACK tools requires jansson
 if test "x${request_hpack_tools}" != "xno" &&
@@ -567,7 +882,7 @@ enable_python_bindings=no
 if test "x${request_python_bindings}" != "xno" &&
    test "x${CYTHON}" != "x" &&
    test "x${PYTHON}" != "x:" &&
-   test "x${have_python_dev}" = "xyes"; then
+   test "x${PYTHON_VERSION}" != "x"; then
   enable_python_bindings=yes
 fi
 
@@ -831,6 +1146,7 @@ AC_CONFIG_FILES([
   src/Makefile
   src/includes/Makefile
   src/libnghttp2_asio.pc
+  bpf/Makefile
   examples/Makefile
   python/Makefile
   python/setup.py
@@ -882,17 +1198,22 @@ AC_MSG_NOTICE([summary of build options:
       WARNCXXFLAGS:   ${WARNCXXFLAGS}
       CXX1XCXXFLAGS:  ${CXX1XCXXFLAGS}
       EXTRACFLAG:     ${EXTRACFLAG}
+      BPFCFLAGS:      ${BPFCFLAGS}
+      EXTRABPFCFLAGS: ${EXTRABPFCFLAGS}
       LIBS:           ${LIBS}
+      DEFS:           ${DEFS}
+      EXTRA_DEFS:     ${EXTRA_DEFS}
     Library:
       Shared:         ${enable_shared}
       Static:         ${enable_static}
+    Libtool:
+      LIBTOOL_LDFLAGS: ${LIBTOOL_LDFLAGS}
     Python:
       Python:         ${PYTHON}
       PYTHON_VERSION: ${PYTHON_VERSION}
       pyexecdir:      ${pyexecdir}
-      Python-dev:     ${have_python_dev}
       PYTHON_CPPFLAGS:${PYTHON_CPPFLAGS}
-      PYTHON_LDFLAGS: ${PYTHON_LDFLAGS}
+      PYTHON_LIBS:    ${PYTHON_LIBS}
       Cython:         ${CYTHON}
     Test:
       CUnit:          ${have_cunit} (CFLAGS='${CUNIT_CFLAGS}' LIBS='${CUNIT_LIBS}')
@@ -902,9 +1223,14 @@ AC_MSG_NOTICE([summary of build options:
       Libxml2:        ${have_libxml2} (CFLAGS='${LIBXML2_CFLAGS}' LIBS='${LIBXML2_LIBS}')
       Libev:          ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}')
       Libc-ares:      ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}')
+      libngtcp2:      ${have_libngtcp2} (CFLAGS='${LIBNGTCP2_CFLAGS}' LIBS='${LIBNGTCP2_LIBS}')
+      libngtcp2_crypto_openssl: ${have_libngtcp2_crypto_openssl} (CFLAGS='${LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_OPENSSL_LIBS}')
+      libngtcp2_crypto_boringssl: ${have_libngtcp2_crypto_boringssl} (CFLAGS='${LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_BORINGSSL_LIBS}')
+      libnghttp3:     ${have_libnghttp3} (CFLAGS='${LIBNGHTTP3_CFLAGS}' LIBS='${LIBNGHTTP3_LIBS}')
+      libbpf:         ${have_libbpf} (CFLAGS='${LIBBPF_CFLAGS}' LIBS='${LIBBPF_LIBS}')
       Libevent(SSL):  ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')
       Jansson:        ${have_jansson} (CFLAGS='${JANSSON_CFLAGS}' LIBS='${JANSSON_LIBS}')
-      Jemalloc:       ${have_jemalloc} (LIBS='${JEMALLOC_LIBS}')
+      Jemalloc:       ${have_jemalloc} (CFLAGS='${JEMALLOC_CFLAGS}' LIBS='${JEMALLOC_LIBS}')
       Zlib:           ${have_zlib} (CFLAGS='${ZLIB_CFLAGS}' LIBS='${ZLIB_LIBS}')
       Systemd:        ${have_libsystemd} (CFLAGS='${SYSTEMD_CFLAGS}' LIBS='${SYSTEMD_LIBS}')
       Boost CPPFLAGS: ${BOOST_CPPFLAGS}
@@ -923,4 +1249,5 @@ AC_MSG_NOTICE([summary of build options:
       Examples:       ${enable_examples}
       Python bindings:${enable_python_bindings}
       Threading:      ${enable_threads}
+      HTTP/3 (EXPERIMENTAL): ${enable_http3}
 ])
index 6c9da01..0d90118 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -166,11 +166,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -189,8 +192,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -201,9 +207,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -212,9 +221,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -252,8 +270,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -384,7 +403,6 @@ ctags CTAGS:
 
 cscope cscopelist:
 
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
diff --git a/depcomp b/depcomp
index 65cbf70..715e343 100755 (executable)
--- a/depcomp
+++ b/depcomp
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
index f3aec84..0667773 100644 (file)
@@ -184,9 +184,9 @@ set(EXTRA_DIST
   sources/python-apiref.rst
   sources/building-android-binary.rst
   sources/contribute.rst
-  _exts/sphinxcontrib/LICENSE.rubydomain
-  _exts/sphinxcontrib/__init__.py
-  _exts/sphinxcontrib/rubydomain.py
+  _exts/rubydomain/LICENSE.rubydomain
+  _exts/rubydomain/__init__.py
+  _exts/rubydomain/rubydomain.py
   _themes/sphinx_rtd_theme/__init__.py
   _themes/sphinx_rtd_theme/breadcrumbs.html
   _themes/sphinx_rtd_theme/footer.html
index f073bfa..ebbd907 100644 (file)
@@ -30,6 +30,8 @@ APIDOCS= \
        nghttp2_check_authority.rst \
        nghttp2_check_header_name.rst \
        nghttp2_check_header_value.rst \
+       nghttp2_check_method.rst \
+       nghttp2_check_path.rst \
        nghttp2_hd_deflate_bound.rst \
        nghttp2_hd_deflate_change_table_size.rst \
        nghttp2_hd_deflate_del.rst \
@@ -203,23 +205,59 @@ EXTRA_DIST = \
        sources/python-apiref.rst \
        sources/building-android-binary.rst \
        sources/contribute.rst \
-       _exts/sphinxcontrib/LICENSE.rubydomain \
-       _exts/sphinxcontrib/__init__.py \
-       _exts/sphinxcontrib/rubydomain.py \
+       sources/security.rst \
+       _exts/rubydomain/LICENSE.rubydomain \
+       _exts/rubydomain/__init__.py \
+       _exts/rubydomain/rubydomain.py \
        _themes/sphinx_rtd_theme/__init__.py \
        _themes/sphinx_rtd_theme/breadcrumbs.html \
        _themes/sphinx_rtd_theme/footer.html \
        _themes/sphinx_rtd_theme/layout.html \
-       _themes/sphinx_rtd_theme/layout_old.html \
+       _themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/sphinx.pot \
+       _themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.po \
        _themes/sphinx_rtd_theme/search.html \
        _themes/sphinx_rtd_theme/searchbox.html \
        _themes/sphinx_rtd_theme/static/css/badge_only.css \
+       _themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.eot \
+       _themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.svg \
+       _themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.ttf \
+       _themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff2 \
        _themes/sphinx_rtd_theme/static/css/theme.css \
-       _themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf \
-       _themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot \
-       _themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg \
-       _themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf \
-       _themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff \
+       _themes/sphinx_rtd_theme/static/js/badge_only.js \
        _themes/sphinx_rtd_theme/static/js/theme.js \
        _themes/sphinx_rtd_theme/theme.conf \
        _themes/sphinx_rtd_theme/versions.html \
@@ -234,7 +272,7 @@ EXTRA_DIST = \
 
 # You can set these variables from the command line.
 SPHINXOPTS    =
-SPHINXBUILD   = sphinx-build
+SPHINXBUILD   ?= sphinx-build
 PAPER         =
 BUILDDIR      = manual
 
index db35c52..bca2ead 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -213,11 +213,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -236,8 +239,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -248,9 +254,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -259,9 +268,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -299,8 +317,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -387,6 +406,8 @@ APIDOCS = \
        nghttp2_check_authority.rst \
        nghttp2_check_header_name.rst \
        nghttp2_check_header_value.rst \
+       nghttp2_check_method.rst \
+       nghttp2_check_path.rst \
        nghttp2_hd_deflate_bound.rst \
        nghttp2_hd_deflate_change_table_size.rst \
        nghttp2_hd_deflate_del.rst \
@@ -560,23 +581,59 @@ EXTRA_DIST = \
        sources/python-apiref.rst \
        sources/building-android-binary.rst \
        sources/contribute.rst \
-       _exts/sphinxcontrib/LICENSE.rubydomain \
-       _exts/sphinxcontrib/__init__.py \
-       _exts/sphinxcontrib/rubydomain.py \
+       sources/security.rst \
+       _exts/rubydomain/LICENSE.rubydomain \
+       _exts/rubydomain/__init__.py \
+       _exts/rubydomain/rubydomain.py \
        _themes/sphinx_rtd_theme/__init__.py \
        _themes/sphinx_rtd_theme/breadcrumbs.html \
        _themes/sphinx_rtd_theme/footer.html \
        _themes/sphinx_rtd_theme/layout.html \
-       _themes/sphinx_rtd_theme/layout_old.html \
+       _themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/sphinx.pot \
+       _themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.po \
+       _themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.mo \
+       _themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.po \
        _themes/sphinx_rtd_theme/search.html \
        _themes/sphinx_rtd_theme/searchbox.html \
        _themes/sphinx_rtd_theme/static/css/badge_only.css \
+       _themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.eot \
+       _themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.svg \
+       _themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.ttf \
+       _themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff2 \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff \
+       _themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff2 \
        _themes/sphinx_rtd_theme/static/css/theme.css \
-       _themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf \
-       _themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot \
-       _themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg \
-       _themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf \
-       _themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff \
+       _themes/sphinx_rtd_theme/static/js/badge_only.js \
        _themes/sphinx_rtd_theme/static/js/theme.js \
        _themes/sphinx_rtd_theme/theme.conf \
        _themes/sphinx_rtd_theme/versions.html \
@@ -592,7 +649,6 @@ EXTRA_DIST = \
 
 # You can set these variables from the command line.
 SPHINXOPTS = 
-SPHINXBUILD = sphinx-build
 PAPER = 
 BUILDDIR = manual
 
@@ -721,7 +777,6 @@ ctags CTAGS:
 
 cscope cscopelist:
 
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -877,6 +932,7 @@ uninstall-man: uninstall-man1
 
 .PRECIOUS: Makefile
 
+SPHINXBUILD   ?= sphinx-build
 
 .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
 
similarity index 95%
rename from doc/_exts/sphinxcontrib/rubydomain.py
rename to doc/_exts/rubydomain/rubydomain.py
index 14114cb..62a0428 100644 (file)
@@ -18,7 +18,7 @@ from docutils.parsers.rst import Directive
 from sphinx import addnodes
 from sphinx import version_info
 from sphinx.roles import XRefRole
-from sphinx.locale import l_, _
+from sphinx.locale import _
 from sphinx.domains import Domain, ObjType, Index
 from sphinx.directives import ObjectDescription
 from sphinx.util.nodes import make_refnode
@@ -64,18 +64,18 @@ class RubyObject(ObjectDescription):
     }
 
     doc_field_types = [
-        TypedField('parameter', label=l_('Parameters'),
+        TypedField('parameter', label=_('Parameters'),
                    names=('param', 'parameter', 'arg', 'argument'),
                    typerolename='obj', typenames=('paramtype', 'type')),
-        TypedField('variable', label=l_('Variables'), rolename='obj',
+        TypedField('variable', label=_('Variables'), rolename='obj',
                    names=('var', 'ivar', 'cvar'),
                    typerolename='obj', typenames=('vartype',)),
-        GroupedField('exceptions', label=l_('Raises'), rolename='exc',
+        GroupedField('exceptions', label=_('Raises'), rolename='exc',
                      names=('raises', 'raise', 'exception', 'except'),
                      can_collapse=True),
-        Field('returnvalue', label=l_('Returns'), has_arg=False,
+        Field('returnvalue', label=_('Returns'), has_arg=False,
               names=('returns', 'return')),
-        Field('returntype', label=l_('Return type'), has_arg=False,
+        Field('returntype', label=_('Return type'), has_arg=False,
               names=('rtype',)),
     ]
 
@@ -482,8 +482,8 @@ class RubyModuleIndex(Index):
     """
 
     name = 'modindex'
-    localname = l_('Ruby Module Index')
-    shortname = l_('modules')
+    localname = _('Ruby Module Index')
+    shortname = _('modules')
 
     def generate(self, docnames=None):
         content = {}
@@ -550,17 +550,17 @@ class RubyDomain(Domain):
     name = 'rb'
     label = 'Ruby'
     object_types = {
-        'function':        ObjType(l_('function'),         'func', 'obj'),
-        'global':          ObjType(l_('global variable'),  'global', 'obj'),
-        'method':          ObjType(l_('method'),           'meth', 'obj'),
-        'class':           ObjType(l_('class'),            'class', 'obj'),
-        'exception':       ObjType(l_('exception'),        'exc', 'obj'),
-        'classmethod':     ObjType(l_('class method'),     'meth', 'obj'),
-        'attr_reader':     ObjType(l_('attribute'),        'attr', 'obj'),
-        'attr_writer':     ObjType(l_('attribute'),        'attr', 'obj'),
-        'attr_accessor':   ObjType(l_('attribute'),        'attr', 'obj'),
-        'const':           ObjType(l_('const'),            'const', 'obj'),
-        'module':          ObjType(l_('module'),           'mod', 'obj'),
+        'function':        ObjType(_('function'),         'func', 'obj'),
+        'global':          ObjType(_('global variable'),  'global', 'obj'),
+        'method':          ObjType(_('method'),           'meth', 'obj'),
+        'class':           ObjType(_('class'),            'class', 'obj'),
+        'exception':       ObjType(_('exception'),        'exc', 'obj'),
+        'classmethod':     ObjType(_('class method'),     'meth', 'obj'),
+        'attr_reader':     ObjType(_('attribute'),        'attr', 'obj'),
+        'attr_writer':     ObjType(_('attribute'),        'attr', 'obj'),
+        'attr_accessor':   ObjType(_('attribute'),        'attr', 'obj'),
+        'const':           ObjType(_('const'),            'const', 'obj'),
+        'module':          ObjType(_('module'),           'mod', 'obj'),
     }
 
     directives = {
index 88ddcce..e48d969 100644 (file)
@@ -1,17 +1,34 @@
-"""Sphinx ReadTheDocs theme.
+"""
+Sphinx Read the Docs theme.
 
 From https://github.com/ryan-roemer/sphinx-bootstrap-theme.
-
 """
-import os
 
-VERSION = (0, 1, 9)
+from os import path
+
+import sphinx
+
 
-__version__ = ".".join(str(v) for v in VERSION)
+__version__ = '0.5.0'
 __version_full__ = __version__
 
 
 def get_html_theme_path():
     """Return list of HTML theme paths."""
-    cur_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
+    cur_dir = path.abspath(path.dirname(path.dirname(__file__)))
     return cur_dir
+
+
+# See http://www.sphinx-doc.org/en/stable/theming.html#distribute-your-theme-as-a-python-package
+def setup(app):
+    if sphinx.version_info >= (1, 6, 0):
+        # Register the theme that can be referenced without adding a theme path
+        app.add_html_theme('sphinx_rtd_theme', path.abspath(path.dirname(__file__)))
+
+    if sphinx.version_info >= (1, 8, 0):
+        # Add Sphinx message catalog for newer versions of Sphinx
+        # See http://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_message_catalog
+        rtd_locale_path = path.join(path.abspath(path.dirname(__file__)), 'locale')
+        app.add_message_catalog('sphinx', rtd_locale_path)
+
+    return {'parallel_read_safe': True, 'parallel_write_safe': True}
index 7c2ce5c..cf64d15 100644 (file)
@@ -1,31 +1,84 @@
 {# Support for Sphinx 1.3+ page_source_suffix, but don't break old builds. #}
 
-{% if page_source_suffix %} 
+{% if page_source_suffix %}
 {% set suffix = page_source_suffix %}
 {% else %}
 {% set suffix = source_suffix %}
 {% endif %}
 
+{% if meta is defined and meta is not none %}
+{% set check_meta = True %}
+{% else %}
+{% set check_meta = False %}
+{% endif %}
+
+{% if check_meta and 'github_url' in meta %}
+{% set display_github = True %}
+{% endif %}
+
+{% if check_meta and 'bitbucket_url' in meta %}
+{% set display_bitbucket = True %}
+{% endif %}
+
+{% if check_meta and 'gitlab_url' in meta %}
+{% set display_gitlab = True %}
+{% endif %}
+
+{% set display_vcs_links = display_vcs_links if display_vcs_links is defined else True %}
+
 <div role="navigation" aria-label="breadcrumbs navigation">
+
   <ul class="wy-breadcrumbs">
-    <li><a href="{{ pathto(master_doc) }}">Docs</a> &raquo;</li>
-      {% for doc in parents %}
-        <li><a href="{{ doc.link|e }}">{{ doc.title }}</a> &raquo;</li>
-      {% endfor %}
-    <li>{{ title }}</li>
-    <li class="wy-breadcrumbs-aside">
-      {% if pagename != "search" %}
-        {% if display_github %}
-          <a href="https://{{ github_host|default("github.com") }}/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-github"> Edit on GitHub</a>
-        {% elif display_bitbucket %}
-          <a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-bitbucket"> Edit on Bitbucket</a>
-        {% elif show_source and source_url_prefix %}
-          <a href="{{ source_url_prefix }}{{ pagename }}{{ suffix }}">View page source</a>
-        {% elif show_source and has_source and sourcename %}
-          <a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> View page source</a>
+    {% block breadcrumbs %}
+      <li><a href="{{ pathto(master_doc) }}" class="icon icon-home"></a> &raquo;</li>
+        {% for doc in parents %}
+          <li><a href="{{ doc.link|e }}">{{ doc.title }}</a> &raquo;</li>
+        {% endfor %}
+      <li>{{ title }}</li>
+    {% endblock %}
+    {% block breadcrumbs_aside %}
+      <li class="wy-breadcrumbs-aside">
+        {% if hasdoc(pagename) and display_vcs_links %}
+          {% if display_github %}
+            {% if check_meta and 'github_url' in meta %}
+              <!-- User defined GitHub URL -->
+              <a href="{{ meta['github_url'] }}" class="fa fa-github"> {{ _('Edit on GitHub') }}</a>
+            {% else %}
+              <a href="https://{{ github_host|default("github.com") }}/{{ github_user }}/{{ github_repo }}/{{ theme_vcs_pageview_mode|default("blob") }}/{{ github_version }}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-github"> {{ _('Edit on GitHub') }}</a>
+            {% endif %}
+          {% elif display_bitbucket %}
+            {% if check_meta and 'bitbucket_url' in meta %}
+              <!-- User defined Bitbucket URL -->
+              <a href="{{ meta['bitbucket_url'] }}" class="fa fa-bitbucket"> {{ _('Edit on Bitbucket') }}</a>
+            {% else %}
+              <a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}{{ suffix }}?mode={{ theme_vcs_pageview_mode|default("view") }}" class="fa fa-bitbucket"> {{ _('Edit on Bitbucket') }}</a>
+            {% endif %}
+          {% elif display_gitlab %}
+            {% if check_meta and 'gitlab_url' in meta %}
+              <!-- User defined GitLab URL -->
+              <a href="{{ meta['gitlab_url'] }}" class="fa fa-gitlab"> {{ _('Edit on GitLab') }}</a>
+            {% else %}
+              <a href="https://{{ gitlab_host|default("gitlab.com") }}/{{ gitlab_user }}/{{ gitlab_repo }}/{{ theme_vcs_pageview_mode|default("blob") }}/{{ gitlab_version }}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-gitlab"> {{ _('Edit on GitLab') }}</a>
+            {% endif %}
+          {% elif show_source and source_url_prefix %}
+            <a href="{{ source_url_prefix }}{{ pagename }}{{ suffix }}">{{ _('View page source') }}</a>
+          {% elif show_source and has_source and sourcename %}
+            <a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> {{ _('View page source') }}</a>
+          {% endif %}
         {% endif %}
-      {% endif %}
-    </li>
+      </li>
+    {% endblock %}
   </ul>
+
+  {% if (theme_prev_next_buttons_location == 'top' or theme_prev_next_buttons_location == 'both') and (next or prev) %}
+  <div class="rst-breadcrumbs-buttons" role="navigation" aria-label="breadcrumb navigation">
+      {% if next %}
+        <a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}" accesskey="n">{{ _('Next') }} <span class="fa fa-arrow-circle-right"></span></a>
+      {% endif %}
+      {% if prev %}
+        <a href="{{ prev.link|e }}" class="btn btn-neutral float-left" title="{{ prev.title|striptags|e }}" accesskey="p"><span class="fa fa-arrow-circle-left"></span> {{ _('Previous') }}</a>
+      {% endif %}
+  </div>
+  {% endif %}
   <hr/>
 </div>
index f4396ee..e1b99c5 100644 (file)
@@ -1,11 +1,11 @@
 <footer>
-  {% if next or prev %}
+  {% if (theme_prev_next_buttons_location == 'bottom' or theme_prev_next_buttons_location == 'both') and (next or prev) %}
     <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
       {% if next %}
-        <a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}" accesskey="n">Next <span class="fa fa-arrow-circle-right"></span></a>
+        <a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}" accesskey="n" rel="next">{{ _('Next') }} <span class="fa fa-arrow-circle-right"></span></a>
       {% endif %}
       {% if prev %}
-        <a href="{{ prev.link|e }}" class="btn btn-neutral" title="{{ prev.title|striptags|e }}" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous</a>
+        <a href="{{ prev.link|e }}" class="btn btn-neutral float-left" title="{{ prev.title|striptags|e }}" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> {{ _('Previous') }}</a>
       {% endif %}
     </div>
   {% endif %}
     <p>
     {%- if show_copyright %}
       {%- if hasdoc('copyright') %}
-        {% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
+        {% set path = pathto('copyright') %}
+        {% set copyright = copyright|e %}
+        &copy; <a href="{{ path }}">{% trans %}Copyright{% endtrans %}</a> {{ copyright }}
       {%- else %}
-        {% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
+        {% set copyright = copyright|e %}
+        &copy; {% trans %}Copyright{% endtrans %} {{ copyright }}
       {%- endif %}
     {%- endif %}
 
     {%- if build_id and build_url %}
-      {% trans build_url=build_url, build_id=build_id %}
-        <span class="build">
-          Build
-          <a href="{{ build_url }}">{{ build_id }}</a>.
-        </span>
-      {% endtrans %}
+      <span class="build">
+        {# Translators: Build is a noun, not a verb #}
+        {% trans %}Build{% endtrans %}
+        <a href="{{ build_url }}">{{ build_id }}</a>.
+      </span>
     {%- elif commit %}
-      {% trans commit=commit %}
-        <span class="commit">
-          Revision <code>{{ commit }}</code>.
-        </span>
-      {% endtrans %}
-    {%- elif last_updated %}
-      {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
+      <span class="commit">
+        {# Translators: the phrase "revision" comes from Git, referring to a commit #}
+        {% trans %}Revision{% endtrans %} <code>{{ commit }}</code>.
+      </span>
+    {%- endif %}
+    {%- if last_updated %}
+      <span class="lastupdated">
+        {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
+      </span>
     {%- endif %}
 
     </p>
   </div>
 
   {%- if show_sphinx %}
-  {% trans %}Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>{% endtrans %}.
+    {% set sphinx_web = '<a href="https://www.sphinx-doc.org/">Sphinx</a>' %}
+    {% set readthedocs_web = '<a href="https://readthedocs.org">Read the Docs</a>'  %}
+    {# Translators: the variable "sphinx_web" is a link to the Sphinx project documentation with the text "Sphinx" #}
+    {% trans sphinx_web=sphinx_web, readthedocs_web=readthedocs_web %}Built with {{ sphinx_web }} using a{% endtrans %}
+    {# Translators: "theme" refers to a theme for Sphinx, which alters the appearance of the generated documenation #}
+    <a href="https://github.com/readthedocs/sphinx_rtd_theme">{% trans %}theme{% endtrans %}</a>
+    {# Translators: this is always used as "provided by Read the Docs", and should not imply Read the Docs is an author of the generated documentation. #}
+    {% trans %}provided by {{ readthedocs_web }}{% endtrans %}.
   {%- endif %}
 
   {%- block extrafooter %} {% endblock %}
index c34fa58..9344063 100644 (file)
@@ -6,10 +6,11 @@
 {%- else %}
   {%- set titlesuffix = "" %}
 {%- endif %}
+{%- set lang_attr = 'en' if language == None else (language | replace('_', '-')) %}
+{%- set sphinx_writer = 'writer-html5' if html5_doctype else 'writer-html4' %}
 
 <!DOCTYPE html>
-<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
+<html class="{{ sphinx_writer }}" lang="{{ lang_attr }}" >
 <head>
   <meta charset="utf-8">
   {{ metatags }}
   <title>{{ title|striptags|e }}{{ titlesuffix }}</title>
   {% endblock %}
 
-  {# FAVICON #}
-  {% if favicon %}
-    <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
-  {% endif %}
-
   {# CSS #}
+  <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
+  <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
+  {%- for css in css_files %}
+    {%- if css|attr("rel") %}
+  <link rel="{{ css.rel }}" href="{{ pathto(css.filename, 1) }}" type="text/css"{% if css.title is not none %} title="{{ css.title }}"{% endif %} />
+    {%- else %}
+  <link rel="stylesheet" href="{{ pathto(css, 1) }}" type="text/css" />
+    {%- endif %}
+  {%- endfor %}
 
-  {# OPENSEARCH #}
-  {% if not embedded %}
-    {% if use_opensearch %}
-      <link rel="search" type="application/opensearchdescription+xml" title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}" href="{{ pathto('_static/opensearch.xml', 1) }}"/>
-    {% endif %}
+  {%- for cssfile in extra_css_files %}
+    <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
+  {%- endfor %}
 
+  {# FAVICON #}
+  {% if favicon %}
+    <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
   {% endif %}
-
-  {# RTD hosts this file, so just load on non RTD builds #}
-  {% if not READTHEDOCS %}
-    <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
+  {# CANONICAL URL #}
+  {% if theme_canonical_url %}
+    <link rel="canonical" href="{{ theme_canonical_url }}{{ pagename }}.html"/>
   {% endif %}
 
-  {% for cssfile in css_files %}
-    <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
-  {% endfor %}
+  {# JAVASCRIPTS #}
+  {%- block scripts %}
+  <!--[if lt IE 9]>
+    <script src="{{ pathto('_static/js/html5shiv.min.js', 1) }}"></script>
+  <![endif]-->
+  {%- if not embedded %}
+  {# XXX Sphinx 1.8.0 made this an external js-file, quick fix until we refactor the template to inherert more blocks directly from sphinx #}
+    {% if sphinx_version >= "1.8.0" %}
+      <script type="text/javascript" id="documentation_options" data-url_root="{{ pathto('', 1) }}" src="{{ pathto('_static/documentation_options.js', 1) }}"></script>
+      {%- for scriptfile in script_files %}
+        {{ js_tag(scriptfile) }}
+      {%- endfor %}
+    {% else %}
+      <script type="text/javascript">
+          var DOCUMENTATION_OPTIONS = {
+              URL_ROOT:'{{ url_root }}',
+              VERSION:'{{ release|e }}',
+              LANGUAGE:'{{ language }}',
+              COLLAPSE_INDEX:false,
+              FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
+              HAS_SOURCE:  {{ has_source|lower }},
+              SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}'
+          };
+      </script>
+      {%- for scriptfile in script_files %}
+        <script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
+      {%- endfor %}
+    {% endif %}
+    <script type="text/javascript" src="{{ pathto('_static/js/theme.js', 1) }}"></script>
 
-  {% for cssfile in extra_css_files %}
-    <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
-  {% endfor %}
+    {# OPENSEARCH #}
+    {%- if use_opensearch %}
+    <link rel="search" type="application/opensearchdescription+xml"
+          title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
+          href="{{ pathto('_static/opensearch.xml', 1) }}"/>
+    {%- endif %}
+  {%- endif %}
+  {%- endblock %}
 
   {%- block linktags %}
     {%- if hasdoc('about') %}
-        <link rel="author" title="{{ _('About these documents') }}"
-              href="{{ pathto('about') }}"/>
+    <link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
     {%- endif %}
     {%- if hasdoc('genindex') %}
-        <link rel="index" title="{{ _('Index') }}"
-              href="{{ pathto('genindex') }}"/>
+    <link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
     {%- endif %}
     {%- if hasdoc('search') %}
-        <link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}"/>
+    <link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
     {%- endif %}
     {%- if hasdoc('copyright') %}
-        <link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}"/>
-    {%- endif %}
-    <link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}"/>
-    {%- if parents %}
-        <link rel="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}"/>
+    <link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
     {%- endif %}
     {%- if next %}
-        <link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}"/>
+    <link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
     {%- endif %}
     {%- if prev %}
-        <link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}"/>
+    <link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
     {%- endif %}
   {%- endblock %}
   {%- block extrahead %} {% endblock %}
-
-  {# Keep modernizr in head - http://modernizr.com/docs/#installing #}
-  <script src="{{ pathto('_static/js/modernizr.min.js', 1) }}"></script>
-
 </head>
 
-<body class="wy-body-for-nav" role="document">
+<body class="wy-body-for-nav">
 
   {% block extrabody %} {% endblock %}
   <div class="wy-grid-for-nav">
-
     {# SIDE NAV, TOGGLES ON MOBILE #}
     <nav data-toggle="wy-nav-shift" class="wy-nav-side">
       <div class="wy-side-scroll">
-        <div class="wy-side-nav-search">
+        <div class="wy-side-nav-search" {% if theme_style_nav_header_background %} style="background: {{theme_style_nav_header_background}}" {% endif %}>
           {% block sidebartitle %}
 
           {% if logo and theme_logo_only %}
           {% endif %}
 
           {% if logo %}
-            {# Not strictly valid HTML, but it's the only way to display/scale it properly, without weird scripting or heaps of work #}
-            <img src="{{ pathto('_static/' + logo, 1) }}" class="logo" />
+            {# Not strictly valid HTML, but it's the only way to display/scale
+               it properly, without weird scripting or heaps of work
+            #}
+            <img src="{{ pathto('_static/' + logo, 1) }}" class="logo" alt="{{ _('Logo') }}"/>
           {% endif %}
           </a>
 
           {% endblock %}
         </div>
 
+        {% block navigation %}
         <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
           {% block menu %}
-            {% set toctree = toctree(maxdepth=4, collapse=theme_collapse_navigation, includehidden=True) %}
-            {% if toctree %}
-                {{ toctree }}
+            {#
+              The singlehtml builder doesn't handle this toctree call when the
+              toctree is empty. Skip building this for now.
+            #}
+            {% if 'singlehtml' not in builder %}
+              {% set global_toc = toctree(maxdepth=theme_navigation_depth|int,
+                                          collapse=theme_collapse_navigation|tobool,
+                                          includehidden=theme_includehidden|tobool,
+                                          titles_only=theme_titles_only|tobool) %}
+            {% endif %}
+            {% if global_toc %}
+              {{ global_toc }}
             {% else %}
-                <!-- Local TOC -->
-                <div class="local-toc">{{ toc }}</div>
+              <!-- Local TOC -->
+              <div class="local-toc">{{ toc }}</div>
             {% endif %}
           {% endblock %}
         </div>
+        {% endblock %}
       </div>
     </nav>
 
     <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
 
       {# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #}
-      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
-        <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
-        <a href="{{ pathto(master_doc) }}">{{ project }}</a>
+      <nav class="wy-nav-top" aria-label="top navigation">
+        {% block mobile_nav %}
+          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
+          <a href="{{ pathto(master_doc) }}">{{ project }}</a>
+        {% endblock %}
       </nav>
 
 
-      {# PAGE CONTENT #}
       <div class="wy-nav-content">
+      {%- block content %}
+        {% if theme_style_external_links|tobool %}
+        <div class="rst-content style-external-links">
+        {% else %}
         <div class="rst-content">
+        {% endif %}
           {% include "breadcrumbs.html" %}
           <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
+          {%- block document %}
            <div itemprop="articleBody">
             {% block body %}{% endblock %}
            </div>
+           {% if self.comments()|trim %}
+           <div class="articleComments">
+            {% block comments %}{% endblock %}
+           </div>
+           {% endif%}
           </div>
+          {%- endblock %}
           {% include "footer.html" %}
         </div>
+      {%- endblock %}
       </div>
 
     </section>
   </div>
   {% include "versions.html" %}
 
-  {% if not embedded %}
-
-    <script type="text/javascript">
-        var DOCUMENTATION_OPTIONS = {
-            URL_ROOT:'{{ url_root }}',
-            VERSION:'{{ release|e }}',
-            COLLAPSE_INDEX:false,
-            FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
-            HAS_SOURCE:  {{ has_source|lower }}
-        };
-    </script>
-    {%- for scriptfile in script_files %}
-      <script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
-    {%- endfor %}
-
-  {% endif %}
-
-  {# RTD hosts this file, so just load on non RTD builds #}
-  {% if not READTHEDOCS %}
-    <script type="text/javascript" src="{{ pathto('_static/js/theme.js', 1) }}"></script>
-  {% endif %}
-
-  {# STICKY NAVIGATION #}
-  {% if theme_sticky_navigation %}
   <script type="text/javascript">
       jQuery(function () {
-          SphinxRtdTheme.StickyNav.enable();
+          SphinxRtdTheme.Navigation.enable({{ 'true' if theme_sticky_navigation|tobool else 'false' }});
       });
   </script>
+
+  {# Do not conflict with RTD insertion of analytics script #}
+  {% if not READTHEDOCS %}
+    {% if theme_analytics_id %}
+    <!-- Theme Analytics -->
+    <script>
+    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
+
+    ga('create', '{{ theme_analytics_id }}', 'auto');
+    ga('send', 'pageview');
+    </script>
+
+    {% endif %}
   {% endif %}
 
   {%- block footer %} {% endblock %}
diff --git a/doc/_themes/sphinx_rtd_theme/layout_old.html b/doc/_themes/sphinx_rtd_theme/layout_old.html
deleted file mode 100644 (file)
index deb8df2..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-{#
-    basic/layout.html
-    ~~~~~~~~~~~~~~~~~
-
-    Master layout template for Sphinx themes.
-
-    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
-    :license: BSD, see LICENSE for details.
-#}
-{%- block doctype -%}
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-{%- endblock %}
-{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
-{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
-{%- set render_sidebar = (not embedded) and (not theme_nosidebar|tobool) and
-                         (sidebars != []) %}
-{%- set url_root = pathto('', 1) %}
-{# XXX necessary? #}
-{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
-{%- if not embedded and docstitle %}
-  {%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
-{%- else %}
-  {%- set titlesuffix = "" %}
-{%- endif %}
-
-{%- macro relbar() %}
-    <div class="related">
-      <h3>{{ _('Navigation') }}</h3>
-      <ul>
-        {%- for rellink in rellinks %}
-        <li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
-          <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
-             {{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
-          {%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
-        {%- endfor %}
-        {%- block rootrellink %}
-        <li><a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a>{{ reldelim1 }}</li>
-        {%- endblock %}
-        {%- for parent in parents %}
-          <li><a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a>{{ reldelim1 }}</li>
-        {%- endfor %}
-        {%- block relbaritems %} {% endblock %}
-      </ul>
-    </div>
-{%- endmacro %}
-
-{%- macro sidebar() %}
-      {%- if render_sidebar %}
-      <div class="sphinxsidebar">
-        <div class="sphinxsidebarwrapper">
-          {%- block sidebarlogo %}
-          {%- if logo %}
-            <p class="logo"><a href="{{ pathto(master_doc) }}">
-              <img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
-            </a></p>
-          {%- endif %}
-          {%- endblock %}
-          {%- if sidebars != None %}
-            {#- new style sidebar: explicitly include/exclude templates #}
-            {%- for sidebartemplate in sidebars %}
-            {%- include sidebartemplate %}
-            {%- endfor %}
-          {%- else %}
-            {#- old style sidebars: using blocks -- should be deprecated #}
-            {%- block sidebartoc %}
-            {%- include "localtoc.html" %}
-            {%- endblock %}
-            {%- block sidebarrel %}
-            {%- include "relations.html" %}
-            {%- endblock %}
-            {%- block sidebarsourcelink %}
-            {%- include "sourcelink.html" %}
-            {%- endblock %}
-            {%- if customsidebar %}
-            {%- include customsidebar %}
-            {%- endif %}
-            {%- block sidebarsearch %}
-            {%- include "searchbox.html" %}
-            {%- endblock %}
-          {%- endif %}
-        </div>
-      </div>
-      {%- endif %}
-{%- endmacro %}
-
-{%- macro script() %}
-    <script type="text/javascript">
-      var DOCUMENTATION_OPTIONS = {
-        URL_ROOT:    '{{ url_root }}',
-        VERSION:     '{{ release|e }}',
-        COLLAPSE_INDEX: false,
-        FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}',
-        HAS_SOURCE:  {{ has_source|lower }}
-      };
-    </script>
-    {%- for scriptfile in script_files %}
-    <script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
-    {%- endfor %}
-{%- endmacro %}
-
-{%- macro css() %}
-    <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
-    <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
-    {%- for cssfile in css_files %}
-    <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
-    {%- endfor %}
-{%- endmacro %}
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset={{ encoding }}" />
-    {{ metatags }}
-    {%- block htmltitle %}
-    <title>{{ title|striptags|e }}{{ titlesuffix }}</title>
-    {%- endblock %}
-    {{ css() }}
-    {%- if not embedded %}
-    {{ script() }}
-    {%- if use_opensearch %}
-    <link rel="search" type="application/opensearchdescription+xml"
-          title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
-          href="{{ pathto('_static/opensearch.xml', 1) }}"/>
-    {%- endif %}
-    {%- if favicon %}
-    <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
-    {%- endif %}
-    {%- endif %}
-{%- block linktags %}
-    {%- if hasdoc('about') %}
-    <link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
-    {%- endif %}
-    {%- if hasdoc('genindex') %}
-    <link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
-    {%- endif %}
-    {%- if hasdoc('search') %}
-    <link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
-    {%- endif %}
-    {%- if hasdoc('copyright') %}
-    <link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
-    {%- endif %}
-    <link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
-    {%- if parents %}
-    <link rel="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}" />
-    {%- endif %}
-    {%- if next %}
-    <link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
-    {%- endif %}
-    {%- if prev %}
-    <link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
-    {%- endif %}
-{%- endblock %}
-{%- block extrahead %} {% endblock %}
-  </head>
-  <body>
-{%- block header %}{% endblock %}
-
-{%- block relbar1 %}{{ relbar() }}{% endblock %}
-
-{%- block content %}
-  {%- block sidebar1 %} {# possible location for sidebar #} {% endblock %}
-
-    <div class="document">
-  {%- block document %}
-      <div class="documentwrapper">
-      {%- if render_sidebar %}
-        <div class="bodywrapper">
-      {%- endif %}
-          <div class="body">
-            {% block body %} {% endblock %}
-          </div>
-      {%- if render_sidebar %}
-        </div>
-      {%- endif %}
-      </div>
-  {%- endblock %}
-
-  {%- block sidebar2 %}{{ sidebar() }}{% endblock %}
-      <div class="clearer"></div>
-    </div>
-{%- endblock %}
-
-{%- block relbar2 %}{{ relbar() }}{% endblock %}
-
-{%- block footer %}
-    <div class="footer">
-    {%- if show_copyright %}
-      {%- if hasdoc('copyright') %}
-        {% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
-      {%- else %}
-        {% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
-      {%- endif %}
-    {%- endif %}
-    {%- if last_updated %}
-      {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
-    {%- endif %}
-    {%- if show_sphinx %}
-      {% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx-doc.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
-    {%- endif %}
-    </div>
-    <p>asdf asdf asdf asdf 22</p>
-{%- endblock %}
-  </body>
-</html>
-
diff --git a/doc/_themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..c135219
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..ae45f65
--- /dev/null
@@ -0,0 +1,143 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+# 
+# Translators:
+# Tom Kunze <transifex.com@tomabrafix.de>, 2019
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 21:44+0000\n"
+"Last-Translator: Tom Kunze <transifex.com@tomabrafix.de>, 2019\n"
+"Language-Team: German (https://www.transifex.com/readthedocs/teams/101354/de/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr "Auf GitHub bearbeiten"
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr "Auf Bitbucket bearbeiten"
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr "Auf GitLab bearbeiten"
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr "Quelltext anzeigen"
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr "Weiter"
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr "Zurück"
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr "Copyright"
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr "Build"
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "Zuletzt aktualisiert am %(last_updated)s."
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation
+#. with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr "Erstellt mit %(sphinx_web)s mit einem"
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr "bereitgestellt von %(readthedocs_web)s"
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "%(docstitle)s durchsuchen"
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr "Über diese Dokumentation"
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr "Index"
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr "Suche"
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr "Logo"
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr "Bitte aktiviere JavaScript, um die Suchfunktion zu nutzen."
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr "Suchergebnisse"
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words are"
+" spelled correctly and that you've selected enough categories."
+msgstr ""
+"Es wurden keine mit deiner Suchanfrage übereinstimmenden Dokumente gefunden."
+" Achte darauf, dass alle Wörter richtig geschrieben sind und dass genug "
+"Kategorien ausgewählt sind."
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr "Dokumentation durchsuchen"
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr "Versionen"
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr "Auf Read the Docs"
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr "Projektübersicht"
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr "Builds"
+
+#~ msgid "Docs"
+#~ msgstr "Dokumentation"
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr "Kostenloses Dokumentationen-Hosting zur Verfügung gestellt von"
diff --git a/doc/_themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..7c07751
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..cbf7e9a
--- /dev/null
@@ -0,0 +1,156 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 15:43-0600\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language: en\n"
+"Language-Team: en <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr ""
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr ""
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr ""
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr ""
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr ""
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr ""
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr ""
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr ""
+
+#. the phrase "revision" comes from Git, referring to a commit
+#: sphinx_rtd_theme/footer.html:37
+msgid "Revision"
+msgstr ""
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr ""
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr ""
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr ""
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:121
+msgid "Documentation Home"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr ""
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr ""
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr ""
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words "
+"are spelled correctly and that you've selected enough categories."
+msgstr ""
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr ""
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr ""
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr ""
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr ""
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr ""
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr ""
+
+#~ msgid "Docs"
+#~ msgstr ""
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr ""
+
diff --git a/doc/_themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..1e7a89b
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..0b69d14
--- /dev/null
@@ -0,0 +1,164 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+# 
+# Translators:
+# Anthony <aj@ohess.org>, 2019
+# Leonardo J. Caballero G. <leonardocaballero@gmail.com>, 2020
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 21:44+0000\n"
+"Last-Translator: Leonardo J. Caballero G. <leonardocaballero@gmail.com>, 2020\n"
+"Language-Team: Spanish (https://www.transifex.com/readthedocs/teams/101354/es/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+"Language: es\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr "Editar en GitHub"
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr "Editar en Bitbucket"
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr "Editar en GitLab"
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr "Ver código fuente de la página"
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr "Siguiente"
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr "Anterior"
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr "Derechos de autor"
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr "Construido"
+
+#. the phrase "revision" comes from Git, referring to a commit
+#: sphinx_rtd_theme/footer.html:37
+msgid "Revision"
+msgstr "Revisión"
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "Actualizado por última vez en %(last_updated)s."
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation
+#. with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr "Construido con %(sphinx_web)s usando un"
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr "tema"
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr "proporcionado por %(readthedocs_web)s"
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "Buscar en %(docstitle)s"
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr "Sobre esta documentación"
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr "Índice"
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr "Búsqueda"
+
+#: sphinx_rtd_theme/layout.html:121
+msgid "Documentation Home"
+msgstr "Inicio de Documentación"
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr "Logotipo"
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr ""
+"Por favor, active JavaScript para habilitar la funcionalidad de búsqueda."
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr "Resultados de la búsqueda"
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words are"
+" spelled correctly and that you've selected enough categories."
+msgstr ""
+"Su búsqueda no coincide con ningún documento. Por favor, asegúrese de que "
+"todas las palabras estén correctamente escritas y que usted haya "
+"seleccionado las suficientes categorías."
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr "Buscar documentos"
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr "Versiones"
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr "Descargas"
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr "En Read the Docs"
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr "Página de Proyecto"
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr "Construcciones"
+
+#~ msgid "Docs"
+#~ msgstr "Documentos"
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr "Alojamiento gratuito de documentos proporcionado por"
diff --git a/doc/_themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..66d4a0c
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/et/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..e221754
--- /dev/null
@@ -0,0 +1,155 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+# 
+# Translators:
+# Anthony <aj@ohess.org>, 2020
+# Ivar Smolin <okul@linux.ee>, 2020
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 21:44+0000\n"
+"Last-Translator: Ivar Smolin <okul@linux.ee>, 2020\n"
+"Language-Team: Estonian (https://www.transifex.com/readthedocs/teams/101354/et/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+"Language: et\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr "Muuda GitHubis"
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr "Muuda Bitbucketis"
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr "Muuda GitLabis"
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr "Vaata lehe lähtekoodi"
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr "Järgmine"
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr "Eelmine"
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr "Autoriõigus"
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr "Ehitus"
+
+#. the phrase "revision" comes from Git, referring to a commit
+#: sphinx_rtd_theme/footer.html:37
+msgid "Revision"
+msgstr "Redaktsioon"
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "Viimati uuendatud  %(last_updated)s."
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation
+#. with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr "Ehitatud %(sphinx_web)s'iga,"
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr "kujundusteema"
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "Otsi dokumendist %(docstitle)s"
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr "Nende dokumentide kirjeldused"
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr "Indeks"
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr "Otsing"
+
+#: sphinx_rtd_theme/layout.html:121
+msgid "Documentation Home"
+msgstr "Dokumentatsiooni kodu"
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr "Logo"
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr "Otsimisfunktsiooni lubamiseks aktiveeri palun JavaScript"
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr "Otsingu tulemused"
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words are"
+" spelled correctly and that you've selected enough categories."
+msgstr ""
+"Sinu otsingule ei vastanud ükski dokument. Palun veendu, et kõik sisestatud "
+"sõnad on õigesti kirjutatud ja sa oled valikud piisaval hulgal kategooriaid."
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr "Otsi dokumente"
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr "Versioonid"
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr "Allalaadimised"
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr "Saidil Read the Docs"
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr "Projekti kodu"
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr "Ehitused"
+
+#~ msgid "Docs"
+#~ msgstr "Dokumendid"
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr "Dokumentatsiooni majutab tasuta"
diff --git a/doc/_themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..a999fd5
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/fr/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..b8c69d9
--- /dev/null
@@ -0,0 +1,154 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+# 
+# Translators:
+# Radina Matic <radina.matic@gmail.com>, 2020
+# Anthony <aj@ohess.org>, 2020
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 21:44+0000\n"
+"Last-Translator: Anthony <aj@ohess.org>, 2020\n"
+"Language-Team: French (https://www.transifex.com/readthedocs/teams/101354/fr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr "Éditer sur GitHub"
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr "Éditer sur Bitbucket"
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr "Éditer sur GitLab"
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr "Afficher la source de la page"
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr "Suivant"
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr "Précédent"
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr "Droits d'auteur"
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr "Compilation"
+
+#. the phrase "revision" comes from Git, referring to a commit
+#: sphinx_rtd_theme/footer.html:37
+msgid "Revision"
+msgstr "Révision"
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "Dernière mise à jour le %(last_updated)s."
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation
+#. with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr "Compilé avec %(sphinx_web)s en utilisant un"
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr "thème"
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr "fourni par %(readthedocs_web)s"
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "Rechercher dans %(docstitle)s"
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr "À propos de cette documentation"
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr "Index"
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr "Rechercher"
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr "Logo"
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr "Activez JavaScript pour accéder à la fonction de recherche."
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr "Résultats de la recherche"
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words are"
+" spelled correctly and that you've selected enough categories."
+msgstr ""
+"Votre recherche ne correspond à aucun document. Assurez-vous que tous les "
+"mots sont correctement orthographiés et que vous avez sélectionné "
+"suffisamment de catégories."
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr "Rechercher docs"
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr "Versions"
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr "Téléchargements"
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr "Accueil du projet"
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr "Compilations"
+
+#~ msgid "Docs"
+#~ msgstr "Docs"
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr "Hébergement gratuit de documents fourni par"
diff --git a/doc/_themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..f0983e2
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..7963c02
--- /dev/null
@@ -0,0 +1,157 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+# 
+# Translators:
+# Jesse Tan, 2019
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 21:44+0000\n"
+"Last-Translator: Jesse Tan, 2019\n"
+"Language-Team: Dutch (https://www.transifex.com/readthedocs/teams/101354/nl/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+"Language: nl\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr "Bewerk op GitHub"
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr "Bewerk op BitBucket"
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr "Bewerk op GitLab"
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr "Bekijk paginabron"
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr "Volgende"
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr "Vorige"
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr "Copyright"
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr "Bouwresultaat"
+
+#. the phrase "revision" comes from Git, referring to a commit
+#: sphinx_rtd_theme/footer.html:37
+msgid "Revision"
+msgstr "Revisie"
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "Laatste update op %(last_updated)s."
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation
+#. with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr "Gebouwd met %(sphinx_web)s met een"
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr "thema"
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr "geleverd door %(readthedocs_web)s"
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "Zoek binnen %(docstitle)s"
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr "Over deze documenten"
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr "Index"
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr "Zoek"
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr "Logo"
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr "Zet JavaScript aan om de zoekfunctie mogelijk te maken."
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr "Zoekresultaten"
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words are"
+" spelled correctly and that you've selected enough categories."
+msgstr ""
+"Zoekpoging vond geen documenten. Zorg ervoor dat alle woorden correct zijn "
+"gespeld en dat voldoende categorieën zijn geselecteerd."
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr "Zoek in documentatie"
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr "Versies"
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr "Downloads"
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr "Op Read the Docs"
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr "Project Home"
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr "Bouwresultaten"
+
+#~ msgid "Docs"
+#~ msgstr "Documentatie"
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr "Gratis hosting voor documentatie verzorgd door"
diff --git a/doc/_themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..b77d9fd
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/pt_BR/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..8b5e760
--- /dev/null
@@ -0,0 +1,159 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+# 
+# Translators:
+# Rafael Fontenelle <rffontenelle@gmail.com>, 2020
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 21:44+0000\n"
+"Last-Translator: Rafael Fontenelle <rffontenelle@gmail.com>, 2020\n"
+"Language-Team: Portuguese (Brazil) (https://www.transifex.com/readthedocs/teams/101354/pt_BR/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+"Language: pt_BR\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr "Editar no GitHub"
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr "Editar no Bitbucket"
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr "Editar no GitLab"
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr "Ver código-fonte da página"
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr "Próximo"
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr "Anterior"
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr "Copyright"
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr "Compilação"
+
+#. the phrase "revision" comes from Git, referring to a commit
+#: sphinx_rtd_theme/footer.html:37
+msgid "Revision"
+msgstr "Revisão"
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "Última atualização em %(last_updated)s."
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation
+#. with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr "Compilado com %(sphinx_web)s usando um"
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr "tema"
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr "fornecido por %(readthedocs_web)s"
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "Pesquisar em %(docstitle)s"
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr "Sobre esses documentos"
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr "Índice"
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr "Pesquisar"
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr "Logo"
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr ""
+"Por favor, ative JavaScript para habilitar a funcionalidade de pesquisa."
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr "Resultados da pesquisa"
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words are"
+" spelled correctly and that you've selected enough categories."
+msgstr ""
+"A sua pesquisa não encontrou nenhum documento correspondente. Verifique se "
+"todas as palavras estão escritas corretamente e se você selecionou "
+"categorias suficientes."
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr "Pesquisar documentos"
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr "Versões"
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr "Downloads"
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr "No Read the Docs"
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr "Página inicial"
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr "Compilações"
+
+#~ msgid "Docs"
+#~ msgstr "Docs"
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr "Hospedagem de documentos livres fornecida por"
diff --git a/doc/_themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..f41b1ce
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..1648d8d
--- /dev/null
@@ -0,0 +1,158 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+# 
+# Translators:
+# Dmitry Shachnev <mitya57@gmail.com>, 2019
+# lvv83 <vlozhkin83@gmail.com>, 2019
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 21:44+0000\n"
+"Last-Translator: lvv83 <vlozhkin83@gmail.com>, 2019\n"
+"Language-Team: Russian (https://www.transifex.com/readthedocs/teams/101354/ru/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+"Language: ru\n"
+"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr "Редактировать на GitHub"
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr "Редактировать на BitBucket"
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr "Редактировать на GitLab"
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr "Просмотреть исходный код страницы"
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr "Следующая"
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr "Предыдущая"
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr "Авторские права"
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr "Сборка"
+
+#. the phrase "revision" comes from Git, referring to a commit
+#: sphinx_rtd_theme/footer.html:37
+msgid "Revision"
+msgstr "Ревизия"
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "Последний раз обновлено %(last_updated)s."
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation
+#. with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr "Собрано при помощи %(sphinx_web)s с использованием"
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr "темы,"
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr "предоставленной %(readthedocs_web)s"
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "Поиск в %(docstitle)s"
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr "Об этих документах"
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr "Алфавитный указатель"
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr "Поиск"
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr "Логотип"
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr "Активируйте JavaScript, чтобы использовать функционал поиска."
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr "Результаты поиска"
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words are"
+" spelled correctly and that you've selected enough categories."
+msgstr ""
+"По Вашему запросу не найдено результатов. Пожалуйста, проверьте, что все "
+"слова написаны правильно, и Вы выбрали нужные категории."
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr "Поиск в документации"
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr "Версии"
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr "Загрузки"
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr "На Read the Docs"
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr "Домашняя страница проекта"
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr "Сборки"
+
+#~ msgid "Docs"
+#~ msgstr "Документация"
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr "Бесплатный хостинг документов, предоставленный"
diff --git a/doc/_themes/sphinx_rtd_theme/locale/sphinx.pot b/doc/_themes/sphinx_rtd_theme/locale/sphinx.pot
new file mode 100644 (file)
index 0000000..ab183f8
--- /dev/null
@@ -0,0 +1,149 @@
+# Translations template for sphinx_rtd_theme.
+# Copyright (C) 2020 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr ""
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr ""
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr ""
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr ""
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr ""
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr ""
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr ""
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr ""
+
+#. the phrase "revision" comes from Git, referring to a commit
+#: sphinx_rtd_theme/footer.html:37
+msgid "Revision"
+msgstr ""
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr ""
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr ""
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr ""
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:121
+msgid "Documentation Home"
+msgstr ""
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr ""
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr ""
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr ""
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words "
+"are spelled correctly and that you've selected enough categories."
+msgstr ""
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr ""
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr ""
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr ""
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr ""
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr ""
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr ""
+
diff --git a/doc/_themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..4357dbc
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/sv/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..e9d80b0
--- /dev/null
@@ -0,0 +1,158 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+# 
+# Translators:
+# Daniel Holmberg <daniel.holmberg97@gmail.com>, 2020
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 21:44+0000\n"
+"Last-Translator: Daniel Holmberg <daniel.holmberg97@gmail.com>, 2020\n"
+"Language-Team: Swedish (https://www.transifex.com/readthedocs/teams/101354/sv/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr "Editera på GitHub"
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr "Editera på Bitbucket"
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr "Editera på GitLab"
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr "Visa sidkälla"
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr "Nästa"
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr "Tillbaka"
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr "Upphovsrätt"
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr "Bygg"
+
+#. the phrase "revision" comes from Git, referring to a commit
+#: sphinx_rtd_theme/footer.html:37
+msgid "Revision"
+msgstr "Ändra"
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "Senast uppdaterad %(last_updated)s."
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation
+#. with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr "Gjord med %(sphinx_web)s med hjälp av"
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr "tema"
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr "erhållet av %(readthedocs_web)s"
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "Sök i %(docstitle)s"
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr "Om dessa dokument"
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr "Index"
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr "Sök"
+
+#: sphinx_rtd_theme/layout.html:121
+msgid "Documentation Home"
+msgstr "Dokumentation Hem"
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr "Logo"
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr ""
+"Var vänlig och aktivera JavaScript för att möjliggöra sökfunktionaliteten."
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr "Sökresultat"
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words are"
+" spelled correctly and that you've selected enough categories."
+msgstr ""
+"Din sökning gav inga träffar. Var vänlig och se till att alla ord är rätt "
+"stavade och att du har valt tillräckligt många kategorier."
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr "Sök i dokumentationen"
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr "Versioner"
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr "Nerladdningar"
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr "På Read the Docs"
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr "Projekt Hem"
+
+#~ msgid "Docs"
+#~ msgstr "Dokumentation"
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr "Gratis dokumentations hysning erhållen av"
diff --git a/doc/_themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..9409dea
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/tr/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..4f75e06
--- /dev/null
@@ -0,0 +1,147 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+# 
+# Translators:
+# BouRock, 2020
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 21:44+0000\n"
+"Last-Translator: BouRock, 2020\n"
+"Language-Team: Turkish (https://www.transifex.com/readthedocs/teams/101354/tr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+"Language: tr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr "GitHub'da Düzenle"
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr "Bitbucket'ta Düzenle"
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr "GitLab'ta Düzenle"
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr "Sayfa kaynağını görüntüle"
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr "Sonraki"
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr "Önceki"
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr "Telif hakkı"
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr "Oluşturma"
+
+#. the phrase "revision" comes from Git, referring to a commit
+#: sphinx_rtd_theme/footer.html:37
+msgid "Revision"
+msgstr "Gözden geçirme"
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "Son olarak %(last_updated)s tarihinde güncellendi."
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr "tema"
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr "kullanılarak %(readthedocs_web)s tarafından sağlanmasıyla oluşturuldu"
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "%(docstitle)s içinde ara"
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr "Bu belgeler hakkında"
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr "Dizin"
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr "Arama"
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr "Logo"
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr ""
+"Arama işlevselliğini etkinleştirmek için lütfen JavaScript'i etkinleştirin."
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr "Arama Sonuçları"
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words are"
+" spelled correctly and that you've selected enough categories."
+msgstr ""
+"Aramanız hiçbir belgeyle eşleşmedi. Lütfen tüm kelimelerin doğru "
+"yazıldığından ve yeterli kategori seçtiğinizden emin olun."
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr "Belgeleri arayın"
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr "Sürümler"
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr "İndirmeler"
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr "Read the Docs Üzerinde"
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr "Proje Ana Sayfa"
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr "Oluşturmalar"
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr "Ücretsiz belge barındırmayı sağlayan"
diff --git a/doc/_themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.mo b/doc/_themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.mo
new file mode 100644 (file)
index 0000000..4e19eea
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.mo differ
diff --git a/doc/_themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.po b/doc/_themes/sphinx_rtd_theme/locale/zh_CN/LC_MESSAGES/sphinx.po
new file mode 100644 (file)
index 0000000..f30abb6
--- /dev/null
@@ -0,0 +1,151 @@
+# English translations for sphinx_rtd_theme.
+# Copyright (C) 2019 ORGANIZATION
+# This file is distributed under the same license as the sphinx_rtd_theme
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
+# 
+# Translators:
+# 王赛 <wangsai@bootcss.com>, 2019
+# Anthony <aj@ohess.org>, 2020
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2020-05-06 13:38-0600\n"
+"PO-Revision-Date: 2019-07-16 21:44+0000\n"
+"Last-Translator: Anthony <aj@ohess.org>, 2020\n"
+"Language-Team: Chinese (China) (https://www.transifex.com/readthedocs/teams/101354/zh_CN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.8.0\n"
+"Language: zh_CN\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
+msgid "Edit on GitHub"
+msgstr "在 GitHub 上修改"
+
+#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
+msgid "Edit on Bitbucket"
+msgstr "在 Bitbucket 上修改"
+
+#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
+msgid "Edit on GitLab"
+msgstr "在 GitLab 上修改"
+
+#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
+msgid "View page source"
+msgstr "查看页面源码"
+
+#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
+msgid "Next"
+msgstr "下一页"
+
+#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
+msgid "Previous"
+msgstr "上一页"
+
+#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
+#: sphinx_rtd_theme/layout.html:96
+msgid "Copyright"
+msgstr "版权所有"
+
+#. Build is a noun, not a verb
+#: sphinx_rtd_theme/footer.html:31
+msgid "Build"
+msgstr "构建"
+
+#: sphinx_rtd_theme/footer.html:41
+#, python-format
+msgid "Last updated on %(last_updated)s."
+msgstr "最后更新时间 %(last_updated)s。"
+
+#. the variable "sphinx_web" is a link to the Sphinx project documentation
+#. with
+#. the text "Sphinx"
+#: sphinx_rtd_theme/footer.html:52
+#, python-format
+msgid "Built with %(sphinx_web)s using a"
+msgstr "利用 %(sphinx_web)s 构建,使用了 "
+
+#. "theme" refers to a theme for Sphinx, which alters the appearance of the
+#. generated documenation
+#: sphinx_rtd_theme/footer.html:54
+msgid "theme"
+msgstr "主题"
+
+#. this is always used as "provided by Read the Docs", and should not imply
+#. Read the Docs is an author of the generated documentation.
+#: sphinx_rtd_theme/footer.html:56
+#, python-format
+msgid "provided by %(readthedocs_web)s"
+msgstr "由 %(readthedocs_web)s开发"
+
+#: sphinx_rtd_theme/layout.html:79
+#, python-format
+msgid "Search within %(docstitle)s"
+msgstr "在 %(docstitle)s中搜索"
+
+#: sphinx_rtd_theme/layout.html:87
+msgid "About these documents"
+msgstr "关于此文档"
+
+#: sphinx_rtd_theme/layout.html:90
+msgid "Index"
+msgstr "索引"
+
+#: sphinx_rtd_theme/layout.html:93 sphinx_rtd_theme/search.html:11
+msgid "Search"
+msgstr "搜索"
+
+#: sphinx_rtd_theme/layout.html:128
+msgid "Logo"
+msgstr "Logo"
+
+#: sphinx_rtd_theme/search.html:29
+msgid "Please activate JavaScript to enable the search functionality."
+msgstr "请启用 JavaScript 以便使用搜索功能"
+
+#. Search is a noun, not a verb
+#: sphinx_rtd_theme/search.html:37
+msgid "Search Results"
+msgstr "搜索结果"
+
+#: sphinx_rtd_theme/search.html:39
+msgid ""
+"Your search did not match any documents. Please make sure that all words are"
+" spelled correctly and that you've selected enough categories."
+msgstr "您的搜索没有匹配到任何文档。请确保所有单词拼写正确,并选择了足够多的类别。"
+
+#: sphinx_rtd_theme/searchbox.html:4
+msgid "Search docs"
+msgstr "在文档中搜索"
+
+#: sphinx_rtd_theme/versions.html:11
+msgid "Versions"
+msgstr "版本列表"
+
+#: sphinx_rtd_theme/versions.html:17
+msgid "Downloads"
+msgstr "下载链接"
+
+#. The phrase "Read the Docs" is not translated
+#: sphinx_rtd_theme/versions.html:24
+msgid "On Read the Docs"
+msgstr "托管于 Read the Docs"
+
+#: sphinx_rtd_theme/versions.html:26
+msgid "Project Home"
+msgstr "项目首页"
+
+#: sphinx_rtd_theme/versions.html:29
+msgid "Builds"
+msgstr "构建"
+
+#~ msgid "Docs"
+#~ msgstr "文档"
+
+#~ msgid "Free document hosting provided by"
+#~ msgstr "此文档免费托管于"
index e3aa9b5..296ef26 100644 (file)
@@ -9,7 +9,11 @@
 #}
 {%- extends "layout.html" %}
 {% set title = _('Search') %}
-{% set script_files = script_files + ['_static/searchtools.js'] %}
+{% set display_vcs_links = False %}
+{%- block scripts %}
+    {{ super() }}
+    <script type="text/javascript" src="{{ pathto('_static/searchtools.js', 1) }}"></script>
+{%- endblock %}
 {% block footer %}
   <script type="text/javascript">
     jQuery(function() { Search.loadIndex("{{ pathto('searchindex.js', 1) }}"); });
   <noscript>
   <div id="fallback" class="admonition warning">
     <p class="last">
-      {% trans %}Please activate JavaScript to enable the search
+      {% trans trimmed %}Please activate JavaScript to enable the search
       functionality.{% endtrans %}
     </p>
   </div>
   </noscript>
 
   {% if search_performed %}
+    {# Translators: Search is a noun, not a verb #}
     <h2>{{ _('Search Results') }}</h2>
     {% if not search_results %}
       <p>{{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}</p>
index 35ad52c..606f5c8 100644 (file)
@@ -1,7 +1,7 @@
 {%- if builder != 'singlehtml' %}
 <div role="search">
   <form id="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get">
-    <input type="text" name="q" placeholder="Search docs" />
+    <input type="text" name="q" placeholder="{{ _('Search docs') }}" />
     <input type="hidden" name="check_keywords" value="yes" />
     <input type="hidden" name="area" value="default" />
   </form>
index 7e17fb1..e380325 100644 (file)
@@ -1,2 +1 @@
-.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}
-/*# sourceMappingURL=badge_only.css.map */
+.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
\ No newline at end of file
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff b/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff
new file mode 100644 (file)
index 0000000..6cb6000
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff2 b/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff2
new file mode 100644 (file)
index 0000000..7059e23
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff2 differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff b/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff
new file mode 100644 (file)
index 0000000..f815f63
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff2 b/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff2
new file mode 100644 (file)
index 0000000..f2c76e5
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff2 differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.eot b/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.eot
new file mode 100644 (file)
index 0000000..e9f60ca
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.eot differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.svg b/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.svg
new file mode 100644 (file)
index 0000000..855c845
--- /dev/null
@@ -0,0 +1,2671 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg>
+<metadata>
+Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016
+ By ,,,
+Copyright Dave Gandy 2016. All rights reserved.
+</metadata>
+<defs>
+<font id="FontAwesome" horiz-adv-x="1536" >
+  <font-face 
+    font-family="FontAwesome"
+    font-weight="400"
+    font-stretch="normal"
+    units-per-em="1792"
+    panose-1="0 0 0 0 0 0 0 0 0 0"
+    ascent="1536"
+    descent="-256"
+    bbox="-1.02083 -256.962 2304.6 1537.02"
+    underline-thickness="0"
+    underline-position="0"
+    unicode-range="U+0020-F500"
+  />
+<missing-glyph horiz-adv-x="896" 
+d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" />
+    <glyph glyph-name=".notdef" horiz-adv-x="896" 
+d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" />
+    <glyph glyph-name=".null" horiz-adv-x="0" 
+ />
+    <glyph glyph-name="nonmarkingreturn" horiz-adv-x="597" 
+ />
+    <glyph glyph-name="space" unicode=" " horiz-adv-x="448" 
+ />
+    <glyph glyph-name="dieresis" unicode="&#xa8;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="copyright" unicode="&#xa9;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="registered" unicode="&#xae;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="acute" unicode="&#xb4;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="AE" unicode="&#xc6;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="Oslash" unicode="&#xd8;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="trademark" unicode="&#x2122;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="infinity" unicode="&#x221e;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="notequal" unicode="&#x2260;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="glass" unicode="&#xf000;" horiz-adv-x="1792" 
+d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
+    <glyph glyph-name="music" unicode="&#xf001;" 
+d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89
+t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
+    <glyph glyph-name="search" unicode="&#xf002;" horiz-adv-x="1664" 
+d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5
+t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
+    <glyph glyph-name="envelope" unicode="&#xf003;" horiz-adv-x="1792" 
+d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13
+t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z
+M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="heart" unicode="&#xf004;" horiz-adv-x="1792" 
+d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600
+q-18 -18 -44 -18z" />
+    <glyph glyph-name="star" unicode="&#xf005;" horiz-adv-x="1664" 
+d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455
+l502 -73q56 -9 56 -46z" />
+    <glyph glyph-name="star_empty" unicode="&#xf006;" horiz-adv-x="1664" 
+d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500
+l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
+    <glyph glyph-name="user" unicode="&#xf007;" horiz-adv-x="1280" 
+d="M1280 137q0 -109 -62.5 -187t-150.5 -78h-854q-88 0 -150.5 78t-62.5 187q0 85 8.5 160.5t31.5 152t58.5 131t94 89t134.5 34.5q131 -128 313 -128t313 128q76 0 134.5 -34.5t94 -89t58.5 -131t31.5 -152t8.5 -160.5zM1024 1024q0 -159 -112.5 -271.5t-271.5 -112.5
+t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
+    <glyph glyph-name="film" unicode="&#xf008;" horiz-adv-x="1920" 
+d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128
+q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45
+t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128
+q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19
+t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="th_large" unicode="&#xf009;" horiz-adv-x="1664" 
+d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38
+h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="th" unicode="&#xf00a;" horiz-adv-x="1792" 
+d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320
+q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28
+h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192
+q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" />
+    <glyph glyph-name="th_list" unicode="&#xf00b;" horiz-adv-x="1792" 
+d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960
+q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28
+h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
+    <glyph glyph-name="ok" unicode="&#xf00c;" horiz-adv-x="1792" 
+d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
+    <glyph glyph-name="remove" unicode="&#xf00d;" horiz-adv-x="1408" 
+d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68
+t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
+    <glyph glyph-name="zoom_in" unicode="&#xf00e;" horiz-adv-x="1664" 
+d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224
+q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5
+t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
+    <glyph glyph-name="zoom_out" unicode="&#xf010;" horiz-adv-x="1664" 
+d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z
+M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z
+" />
+    <glyph glyph-name="off" unicode="&#xf011;" 
+d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5
+t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
+    <glyph glyph-name="signal" unicode="&#xf012;" horiz-adv-x="1792" 
+d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23
+v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="cog" unicode="&#xf013;" 
+d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38
+q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13
+l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22
+q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
+    <glyph glyph-name="trash" unicode="&#xf014;" horiz-adv-x="1408" 
+d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576
+q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832
+q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="home" unicode="&#xf015;" horiz-adv-x="1664" 
+d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5
+l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
+    <glyph glyph-name="file_alt" unicode="&#xf016;" 
+d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
+" />
+    <glyph glyph-name="time" unicode="&#xf017;" 
+d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640
+q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="road" unicode="&#xf018;" horiz-adv-x="1920" 
+d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256
+q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
+    <glyph glyph-name="download_alt" unicode="&#xf019;" horiz-adv-x="1664" 
+d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136
+q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
+    <glyph glyph-name="download" unicode="&#xf01a;" 
+d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273
+t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="upload" unicode="&#xf01b;" 
+d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198
+t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="inbox" unicode="&#xf01c;" 
+d="M1023 576h316q-1 3 -2.5 8.5t-2.5 7.5l-212 496h-708l-212 -496q-1 -3 -2.5 -8.5t-2.5 -7.5h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552
+q25 -61 25 -123z" />
+    <glyph glyph-name="play_circle" unicode="&#xf01d;" 
+d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640
+q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="repeat" unicode="&#xf01e;" 
+d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q15 0 25 -9
+l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
+    <glyph glyph-name="refresh" unicode="&#xf021;" 
+d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117
+q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5
+q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
+    <glyph glyph-name="list_alt" unicode="&#xf022;" horiz-adv-x="1792" 
+d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z
+M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5
+t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47
+t47 -113z" />
+    <glyph glyph-name="lock" unicode="&#xf023;" horiz-adv-x="1152" 
+d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
+    <glyph glyph-name="flag" unicode="&#xf024;" horiz-adv-x="1792" 
+d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48
+t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="headphones" unicode="&#xf025;" horiz-adv-x="1664" 
+d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78
+t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5
+t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
+    <glyph glyph-name="volume_off" unicode="&#xf026;" horiz-adv-x="768" 
+d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
+    <glyph glyph-name="volume_down" unicode="&#xf027;" horiz-adv-x="1152" 
+d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36
+t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
+    <glyph glyph-name="volume_up" unicode="&#xf028;" horiz-adv-x="1664" 
+d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36
+t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5
+t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289
+t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
+    <glyph glyph-name="qrcode" unicode="&#xf029;" horiz-adv-x="1408" 
+d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z
+M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
+    <glyph glyph-name="barcode" unicode="&#xf02a;" horiz-adv-x="1792" 
+d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z
+M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
+    <glyph glyph-name="tag" unicode="&#xf02b;" 
+d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5
+l715 -714q37 -39 37 -91z" />
+    <glyph glyph-name="tags" unicode="&#xf02c;" horiz-adv-x="1920" 
+d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5
+l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
+    <glyph glyph-name="book" unicode="&#xf02d;" horiz-adv-x="1664" 
+d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23
+q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906
+q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5
+t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
+    <glyph glyph-name="bookmark" unicode="&#xf02e;" horiz-adv-x="1280" 
+d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
+    <glyph glyph-name="print" unicode="&#xf02f;" horiz-adv-x="1664" 
+d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68
+v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
+    <glyph glyph-name="camera" unicode="&#xf030;" horiz-adv-x="1920" 
+d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136
+q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+    <glyph glyph-name="font" unicode="&#xf031;" horiz-adv-x="1664" 
+d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57
+q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -5 -0.5 -13.5t-0.5 -12.5q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5
+q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" />
+    <glyph glyph-name="bold" unicode="&#xf032;" horiz-adv-x="1408" 
+d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142
+q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5
+t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68 -0.5t68 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5
+t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" />
+    <glyph glyph-name="italic" unicode="&#xf033;" horiz-adv-x="1024" 
+d="M0 -126l17 85q22 7 61.5 16.5t72 19t59.5 23.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5
+q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
+    <glyph glyph-name="text_height" unicode="&#xf034;" horiz-adv-x="1792" 
+d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2
+t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5
+q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27
+q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" />
+    <glyph glyph-name="text_width" unicode="&#xf035;" 
+d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1
+t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27
+q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5
+t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49
+t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" />
+    <glyph glyph-name="align_left" unicode="&#xf036;" horiz-adv-x="1792" 
+d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45
+t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="align_center" unicode="&#xf037;" horiz-adv-x="1792" 
+d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19
+h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="align_right" unicode="&#xf038;" horiz-adv-x="1792" 
+d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45
+t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="align_justify" unicode="&#xf039;" horiz-adv-x="1792" 
+d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45
+t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="list" unicode="&#xf03a;" horiz-adv-x="1792" 
+d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5
+t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344
+q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5
+t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192
+q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
+    <glyph glyph-name="indent_left" unicode="&#xf03b;" horiz-adv-x="1792" 
+d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5
+t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088
+q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
+    <glyph glyph-name="indent_right" unicode="&#xf03c;" horiz-adv-x="1792" 
+d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5
+t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088
+q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
+    <glyph glyph-name="facetime_video" unicode="&#xf03d;" horiz-adv-x="1792" 
+d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5
+q39 -17 39 -59z" />
+    <glyph glyph-name="picture" unicode="&#xf03e;" horiz-adv-x="1920" 
+d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216
+q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="pencil" unicode="&#xf040;" 
+d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38
+q53 0 91 -38l235 -234q37 -39 37 -91z" />
+    <glyph glyph-name="map_marker" unicode="&#xf041;" horiz-adv-x="1024" 
+d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
+    <glyph glyph-name="adjust" unicode="&#xf042;" 
+d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="tint" unicode="&#xf043;" horiz-adv-x="1024" 
+d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362
+q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
+    <glyph glyph-name="edit" unicode="&#xf044;" horiz-adv-x="1792" 
+d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832
+q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92
+l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
+    <glyph glyph-name="share" unicode="&#xf045;" horiz-adv-x="1664" 
+d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832
+q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5
+t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
+    <glyph glyph-name="check" unicode="&#xf046;" horiz-adv-x="1664" 
+d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832
+q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110
+q24 -24 24 -57t-24 -57z" />
+    <glyph glyph-name="move" unicode="&#xf047;" horiz-adv-x="1792" 
+d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45
+t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
+    <glyph glyph-name="step_backward" unicode="&#xf048;" horiz-adv-x="1024" 
+d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19z" />
+    <glyph glyph-name="fast_backward" unicode="&#xf049;" horiz-adv-x="1792" 
+d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19l710 710
+q19 19 32 13t13 -32v-710q4 10 13 19z" />
+    <glyph glyph-name="backward" unicode="&#xf04a;" horiz-adv-x="1664" 
+d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q4 10 13 19z" />
+    <glyph glyph-name="play" unicode="&#xf04b;" horiz-adv-x="1408" 
+d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
+    <glyph glyph-name="pause" unicode="&#xf04c;" 
+d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="stop" unicode="&#xf04d;" 
+d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="forward" unicode="&#xf04e;" horiz-adv-x="1664" 
+d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" />
+    <glyph glyph-name="fast_forward" unicode="&#xf050;" horiz-adv-x="1792" 
+d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19l-710 -710
+q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" />
+    <glyph glyph-name="step_forward" unicode="&#xf051;" horiz-adv-x="1024" 
+d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19z" />
+    <glyph glyph-name="eject" unicode="&#xf052;" horiz-adv-x="1538" 
+d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
+    <glyph glyph-name="chevron_left" unicode="&#xf053;" horiz-adv-x="1280" 
+d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" />
+    <glyph glyph-name="chevron_right" unicode="&#xf054;" horiz-adv-x="1280" 
+d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" />
+    <glyph glyph-name="plus_sign" unicode="&#xf055;" 
+d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5
+t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="minus_sign" unicode="&#xf056;" 
+d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
+t103 -385.5z" />
+    <glyph glyph-name="remove_sign" unicode="&#xf057;" 
+d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19
+q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="ok_sign" unicode="&#xf058;" 
+d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
+t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="question_sign" unicode="&#xf059;" 
+d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59
+q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
+t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="info_sign" unicode="&#xf05a;" 
+d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23
+t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="screenshot" unicode="&#xf05b;" 
+d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109
+q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143
+q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="remove_circle" unicode="&#xf05c;" 
+d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23
+l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5
+t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="ok_circle" unicode="&#xf05d;" 
+d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198
+t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="ban_circle" unicode="&#xf05e;" 
+d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61
+t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
+    <glyph glyph-name="arrow_left" unicode="&#xf060;" 
+d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5
+t32.5 -90.5z" />
+    <glyph glyph-name="arrow_right" unicode="&#xf061;" 
+d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
+    <glyph glyph-name="arrow_up" unicode="&#xf062;" horiz-adv-x="1664" 
+d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651
+q37 -39 37 -91z" />
+    <glyph glyph-name="arrow_down" unicode="&#xf063;" horiz-adv-x="1664" 
+d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
+    <glyph glyph-name="share_alt" unicode="&#xf064;" horiz-adv-x="1792" 
+d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22
+t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
+    <glyph glyph-name="resize_full" unicode="&#xf065;" 
+d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332
+q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="resize_small" unicode="&#xf066;" 
+d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45
+t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
+    <glyph glyph-name="plus" unicode="&#xf067;" horiz-adv-x="1408" 
+d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
+    <glyph glyph-name="minus" unicode="&#xf068;" horiz-adv-x="1408" 
+d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
+    <glyph glyph-name="asterisk" unicode="&#xf069;" horiz-adv-x="1664" 
+d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154
+q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
+    <glyph glyph-name="exclamation_sign" unicode="&#xf06a;" 
+d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192
+q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
+    <glyph glyph-name="gift" unicode="&#xf06b;" 
+d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320
+q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5
+t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="leaf" unicode="&#xf06c;" horiz-adv-x="1792" 
+d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268
+q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-43 0 -63.5 17.5t-45.5 59.5q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5
+t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
+    <glyph glyph-name="fire" unicode="&#xf06d;" horiz-adv-x="1408" 
+d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1
+q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
+    <glyph glyph-name="eye_open" unicode="&#xf06e;" horiz-adv-x="1792" 
+d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5
+t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
+    <glyph glyph-name="eye_close" unicode="&#xf070;" horiz-adv-x="1792" 
+d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9
+q-106 -189 -316 -567t-315 -566l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5
+q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z
+" />
+    <glyph glyph-name="warning_sign" unicode="&#xf071;" horiz-adv-x="1792" 
+d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185
+q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
+    <glyph glyph-name="plane" unicode="&#xf072;" horiz-adv-x="1408" 
+d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9
+q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
+    <glyph glyph-name="calendar" unicode="&#xf073;" horiz-adv-x="1664" 
+d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z
+M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64
+q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47
+h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="random" unicode="&#xf074;" horiz-adv-x="1792" 
+d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1
+t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5
+v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111
+t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
+    <glyph glyph-name="comment" unicode="&#xf075;" horiz-adv-x="1792" 
+d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281
+q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
+    <glyph glyph-name="magnet" unicode="&#xf076;" 
+d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384
+q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="chevron_up" unicode="&#xf077;" horiz-adv-x="1792" 
+d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
+    <glyph glyph-name="chevron_down" unicode="&#xf078;" horiz-adv-x="1792" 
+d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
+    <glyph glyph-name="retweet" unicode="&#xf079;" horiz-adv-x="1920" 
+d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -10 7 -21
+zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z
+" />
+    <glyph glyph-name="shopping_cart" unicode="&#xf07a;" horiz-adv-x="1664" 
+d="M640 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45
+t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="folder_close" unicode="&#xf07b;" horiz-adv-x="1664" 
+d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
+    <glyph glyph-name="folder_open" unicode="&#xf07c;" horiz-adv-x="1920" 
+d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5
+t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
+    <glyph glyph-name="resize_vertical" unicode="&#xf07d;" horiz-adv-x="768" 
+d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
+    <glyph glyph-name="resize_horizontal" unicode="&#xf07e;" horiz-adv-x="1792" 
+d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
+    <glyph glyph-name="bar_chart" unicode="&#xf080;" horiz-adv-x="2048" 
+d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
+    <glyph glyph-name="twitter_sign" unicode="&#xf081;" 
+d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4
+q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5
+t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="facebook_sign" unicode="&#xf082;" 
+d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960
+q0 119 84.5 203.5t203.5 84.5h960z" />
+    <glyph glyph-name="camera_retro" unicode="&#xf083;" horiz-adv-x="1792" 
+d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5
+t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280
+q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
+    <glyph glyph-name="key" unicode="&#xf084;" horiz-adv-x="1792" 
+d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26
+l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5
+t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
+    <glyph glyph-name="cogs" unicode="&#xf085;" horiz-adv-x="1920" 
+d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5
+t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -11 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5
+l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7
+l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -8 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31
+q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20
+t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68
+q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70
+q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
+    <glyph glyph-name="comments" unicode="&#xf086;" horiz-adv-x="1792" 
+d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224
+q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7
+q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
+    <glyph glyph-name="thumbs_up_alt" unicode="&#xf087;" 
+d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5
+t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769
+q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128
+q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
+    <glyph glyph-name="thumbs_down_alt" unicode="&#xf088;" 
+d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 31 18 69q0 37 -17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5
+t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z
+M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5
+h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -73 49 -163z" />
+    <glyph glyph-name="star_half" unicode="&#xf089;" horiz-adv-x="896" 
+d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
+    <glyph glyph-name="heart_empty" unicode="&#xf08a;" horiz-adv-x="1792" 
+d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559
+q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5
+q224 0 351 -124t127 -344z" />
+    <glyph glyph-name="signout" unicode="&#xf08b;" horiz-adv-x="1664" 
+d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704
+q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
+    <glyph glyph-name="linkedin_sign" unicode="&#xf08c;" 
+d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5
+q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="pushpin" unicode="&#xf08d;" horiz-adv-x="1152" 
+d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38
+t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
+    <glyph glyph-name="external_link" unicode="&#xf08e;" horiz-adv-x="1792" 
+d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320
+q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="signin" unicode="&#xf090;" 
+d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5
+q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="trophy" unicode="&#xf091;" horiz-adv-x="1664" 
+d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91
+t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96
+q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
+    <glyph glyph-name="github_sign" unicode="&#xf092;" 
+d="M519 336q4 6 -3 13q-9 7 -14 2q-4 -6 3 -13q9 -7 14 -2zM491 377q-5 7 -12 4q-6 -4 0 -12q7 -8 12 -5q6 4 0 13zM450 417q2 4 -5 8q-7 2 -8 -2q-3 -5 4 -8q8 -2 9 2zM471 394q2 1 1.5 4.5t-3.5 5.5q-6 7 -10 3t1 -11q6 -6 11 -2zM557 319q2 7 -9 11q-9 3 -13 -4
+q-2 -7 9 -11q9 -3 13 4zM599 316q0 8 -12 8q-10 0 -10 -8t11 -8t11 8zM638 323q-2 7 -13 5t-9 -9q2 -8 12 -6t10 10zM1280 640q0 212 -150 362t-362 150t-362 -150t-150 -362q0 -167 98 -300.5t252 -185.5q18 -3 26.5 5t8.5 20q0 52 -1 95q-6 -1 -15.5 -2.5t-35.5 -2t-48 4
+t-43.5 20t-29.5 41.5q-23 59 -57 74q-2 1 -4.5 3.5l-8 8t-7 9.5t4 7.5t19.5 3.5q6 0 15 -2t30 -15.5t33 -35.5q16 -28 37.5 -42t43.5 -14t38 3.5t30 9.5q7 47 33 69q-49 6 -86 18.5t-73 39t-55.5 76t-19.5 119.5q0 79 53 137q-24 62 5 136q19 6 54.5 -7.5t60.5 -29.5l26 -16
+q58 17 128 17t128 -17q11 7 28.5 18t55.5 26t57 9q29 -74 5 -136q53 -58 53 -137q0 -57 -14 -100.5t-35.5 -70t-53.5 -44.5t-62.5 -26t-68.5 -12q35 -31 35 -95q0 -40 -0.5 -89t-0.5 -51q0 -12 8.5 -20t26.5 -5q154 52 252 185.5t98 300.5zM1536 1120v-960
+q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="upload_alt" unicode="&#xf093;" horiz-adv-x="1664" 
+d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92
+t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
+    <glyph glyph-name="lemon" unicode="&#xf094;" 
+d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5
+q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44
+q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5
+q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -13 2 -25t3.5 -16.5t7.5 -20.5t8 -20q16 -40 25 -118.5t9 -136.5z" />
+    <glyph glyph-name="phone" unicode="&#xf095;" horiz-adv-x="1408" 
+d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -53 3.5t-57.5 12.5t-47 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-127 79 -264 216t-216 264q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47t-12.5 57.5t-3.5 53q0 92 51 186
+q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174q2 -1 19 -11.5t24 -14
+t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
+    <glyph glyph-name="check_empty" unicode="&#xf096;" horiz-adv-x="1408" 
+d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832
+q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="bookmark_empty" unicode="&#xf097;" horiz-adv-x="1280" 
+d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289
+q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
+    <glyph glyph-name="phone_sign" unicode="&#xf098;" 
+d="M1280 343q0 11 -2 16t-18 16.5t-40.5 25t-47.5 26.5t-45.5 25t-28.5 15q-5 3 -19 13t-25 15t-21 5q-15 0 -36.5 -20.5t-39.5 -45t-38.5 -45t-33.5 -20.5q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170 126.5t-127 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5
+t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5
+t320.5 -216.5q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z
+" />
+    <glyph glyph-name="twitter" unicode="&#xf099;" horiz-adv-x="1664" 
+d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41
+q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
+    <glyph glyph-name="facebook" unicode="&#xf09a;" horiz-adv-x="1024" 
+d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" />
+    <glyph glyph-name="github" unicode="&#xf09b;" 
+d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -40 7t-13 30q0 3 0.5 76.5t0.5 134.5q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 119 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24
+q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-85 13.5q-45 -113 -8 -204q-79 -87 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-39 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5
+t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -88.5t0.5 -54.5q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103zM291 305q3 7 -7 12
+q-10 3 -13 -2q-3 -7 7 -12q9 -6 13 2zM322 271q7 5 -2 16q-10 9 -16 3q-7 -5 2 -16q10 -10 16 -3zM352 226q9 7 0 19q-8 13 -17 6q-9 -5 0 -18t17 -7zM394 184q8 8 -4 19q-12 12 -20 3q-9 -8 4 -19q12 -12 20 -3zM451 159q3 11 -13 16q-15 4 -19 -7t13 -15q15 -6 19 6z
+M514 154q0 13 -17 11q-16 0 -16 -11q0 -13 17 -11q16 0 16 11zM572 164q-2 11 -18 9q-16 -3 -14 -15t18 -8t14 14z" />
+    <glyph glyph-name="unlock" unicode="&#xf09c;" horiz-adv-x="1664" 
+d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5
+t316.5 -131.5t131.5 -316.5z" />
+    <glyph glyph-name="credit_card" unicode="&#xf09d;" horiz-adv-x="1920" 
+d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608
+q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
+    <glyph glyph-name="rss" unicode="&#xf09e;" horiz-adv-x="1408" 
+d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5
+t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294
+q187 -186 294 -425.5t120 -501.5z" />
+    <glyph glyph-name="hdd" unicode="&#xf0a0;" 
+d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5
+h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75
+l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
+    <glyph glyph-name="bullhorn" unicode="&#xf0a1;" horiz-adv-x="1792" 
+d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5
+t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
+    <glyph glyph-name="bell" unicode="&#xf0a2;" horiz-adv-x="1792" 
+d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z
+M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5
+t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
+    <glyph glyph-name="certificate" unicode="&#xf0a3;" 
+d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70
+l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70
+l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
+    <glyph glyph-name="hand_right" unicode="&#xf0a4;" horiz-adv-x="1792" 
+d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106
+q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43
+q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5
+t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
+    <glyph glyph-name="hand_left" unicode="&#xf0a5;" horiz-adv-x="1792" 
+d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-8 9 -12 14q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5
+t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45z
+M1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67
+q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
+    <glyph glyph-name="hand_up" unicode="&#xf0a6;" 
+d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576
+q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5
+t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76
+q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
+    <glyph glyph-name="hand_down" unicode="&#xf0a7;" 
+d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33
+t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580
+q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100
+q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
+    <glyph glyph-name="circle_arrow_left" unicode="&#xf0a8;" 
+d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640
+q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="circle_arrow_right" unicode="&#xf0a9;" 
+d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640
+q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="circle_arrow_up" unicode="&#xf0aa;" 
+d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640
+q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="circle_arrow_down" unicode="&#xf0ab;" 
+d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640
+q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="globe" unicode="&#xf0ac;" 
+d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11
+q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 11t-9.5 10q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5
+q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5
+q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5
+t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-4 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3
+q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25
+q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5
+t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5
+t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10.5t17 -19.5q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21
+q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5
+q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3
+q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5
+t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q8 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5
+q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7
+q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" />
+    <glyph glyph-name="wrench" unicode="&#xf0ad;" horiz-adv-x="1664" 
+d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5
+t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" />
+    <glyph glyph-name="tasks" unicode="&#xf0ae;" horiz-adv-x="1792" 
+d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19
+t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="filter" unicode="&#xf0b0;" horiz-adv-x="1408" 
+d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" />
+    <glyph glyph-name="briefcase" unicode="&#xf0b1;" horiz-adv-x="1792" 
+d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68
+t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="fullscreen" unicode="&#xf0b2;" 
+d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144
+l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z
+" />
+    <glyph glyph-name="group" unicode="&#xf0c0;" horiz-adv-x="1920" 
+d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5
+t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75
+t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5
+t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" />
+    <glyph glyph-name="link" unicode="&#xf0c1;" horiz-adv-x="1664" 
+d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26
+l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15
+t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207
+q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" />
+    <glyph glyph-name="cloud" unicode="&#xf0c2;" horiz-adv-x="1920" 
+d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z
+" />
+    <glyph glyph-name="beaker" unicode="&#xf0c3;" horiz-adv-x="1664" 
+d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" />
+    <glyph glyph-name="cut" unicode="&#xf0c4;" horiz-adv-x="1792" 
+d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84
+q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148
+q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108
+q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6
+q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
+    <glyph glyph-name="copy" unicode="&#xf0c5;" horiz-adv-x="1792" 
+d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299
+h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" />
+    <glyph glyph-name="paper_clip" unicode="&#xf0c6;" horiz-adv-x="1408" 
+d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181
+l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235
+z" />
+    <glyph glyph-name="save" unicode="&#xf0c7;" 
+d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5
+h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" />
+    <glyph glyph-name="sign_blank" unicode="&#xf0c8;" 
+d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="reorder" unicode="&#xf0c9;" 
+d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45
+t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="ul" unicode="&#xf0ca;" horiz-adv-x="1792" 
+d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5
+t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z
+M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
+    <glyph glyph-name="ol" unicode="&#xf0cb;" horiz-adv-x="1792" 
+d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362
+q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5
+t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 121.5t0.5 121.5v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216
+q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
+    <glyph glyph-name="strikethrough" unicode="&#xf0cc;" horiz-adv-x="1792" 
+d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 98 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6
+l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -56 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23
+l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" />
+    <glyph glyph-name="underline" unicode="&#xf0cd;" 
+d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47
+q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41
+q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472
+q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" />
+    <glyph glyph-name="table" unicode="&#xf0ce;" horiz-adv-x="1664" 
+d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23
+v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192
+q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192
+q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113
+z" />
+    <glyph glyph-name="magic" unicode="&#xf0d0;" horiz-adv-x="1664" 
+d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276
+l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" />
+    <glyph glyph-name="truck" unicode="&#xf0d1;" horiz-adv-x="1792" 
+d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5
+t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38
+t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="pinterest" unicode="&#xf0d2;" 
+d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134
+q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33
+q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="pinterest_sign" unicode="&#xf0d3;" 
+d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5
+t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5
+t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" />
+    <glyph glyph-name="google_plus_sign" unicode="&#xf0d4;" 
+d="M917 631q0 26 -6 64h-362v-132h217q-3 -24 -16.5 -50t-37.5 -53t-66.5 -44.5t-96.5 -17.5q-99 0 -169 71t-70 171t70 171t169 71q92 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585
+h109v110h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="google_plus" unicode="&#xf0d5;" horiz-adv-x="2304" 
+d="M1437 623q0 -208 -87 -370.5t-248 -254t-369 -91.5q-149 0 -285 58t-234 156t-156 234t-58 285t58 285t156 234t234 156t285 58q286 0 491 -192l-199 -191q-117 113 -292 113q-123 0 -227.5 -62t-165.5 -168.5t-61 -232.5t61 -232.5t165.5 -168.5t227.5 -62
+q83 0 152.5 23t114.5 57.5t78.5 78.5t49 83t21.5 74h-416v252h692q12 -63 12 -122zM2304 745v-210h-209v-209h-210v209h-209v210h209v209h210v-209h209z" />
+    <glyph glyph-name="money" unicode="&#xf0d6;" horiz-adv-x="1920" 
+d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384
+v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="caret_down" unicode="&#xf0d7;" horiz-adv-x="1024" 
+d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="caret_up" unicode="&#xf0d8;" horiz-adv-x="1024" 
+d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
+    <glyph glyph-name="caret_left" unicode="&#xf0d9;" horiz-adv-x="640" 
+d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" />
+    <glyph glyph-name="caret_right" unicode="&#xf0da;" horiz-adv-x="640" 
+d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" />
+    <glyph glyph-name="columns" unicode="&#xf0db;" horiz-adv-x="1664" 
+d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="sort" unicode="&#xf0dc;" horiz-adv-x="1024" 
+d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
+    <glyph glyph-name="sort_down" unicode="&#xf0dd;" horiz-adv-x="1024" 
+d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="sort_up" unicode="&#xf0de;" horiz-adv-x="1024" 
+d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
+    <glyph glyph-name="envelope_alt" unicode="&#xf0e0;" horiz-adv-x="1792" 
+d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123
+q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" />
+    <glyph glyph-name="linkedin" unicode="&#xf0e1;" 
+d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329
+q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" />
+    <glyph glyph-name="undo" unicode="&#xf0e2;" 
+d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5
+t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" />
+    <glyph glyph-name="legal" unicode="&#xf0e3;" horiz-adv-x="1792" 
+d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5
+t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14
+q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28
+q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" />
+    <glyph glyph-name="dashboard" unicode="&#xf0e4;" horiz-adv-x="1792" 
+d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5
+t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5
+t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29
+q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="comment_alt" unicode="&#xf0e5;" horiz-adv-x="1792" 
+d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640
+q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5
+t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
+    <glyph glyph-name="comments_alt" unicode="&#xf0e6;" horiz-adv-x="1792" 
+d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257
+t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5
+t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129
+q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" />
+    <glyph glyph-name="bolt" unicode="&#xf0e7;" horiz-adv-x="896" 
+d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" />
+    <glyph glyph-name="sitemap" unicode="&#xf0e8;" horiz-adv-x="1792" 
+d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320
+q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68
+z" />
+    <glyph glyph-name="umbrella" unicode="&#xf0e9;" horiz-adv-x="1664" 
+d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97
+q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69
+q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" />
+    <glyph glyph-name="paste" unicode="&#xf0ea;" horiz-adv-x="1792" 
+d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28
+h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" />
+    <glyph glyph-name="light_bulb" unicode="&#xf0eb;" horiz-adv-x="1024" 
+d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134
+q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47
+q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5
+t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" />
+    <glyph glyph-name="exchange" unicode="&#xf0ec;" horiz-adv-x="1792" 
+d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9
+q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
+    <glyph glyph-name="cloud_download" unicode="&#xf0ed;" horiz-adv-x="1920" 
+d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088
+q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
+    <glyph glyph-name="cloud_upload" unicode="&#xf0ee;" horiz-adv-x="1920" 
+d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088
+q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
+    <glyph glyph-name="user_md" unicode="&#xf0f0;" horiz-adv-x="1408" 
+d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56
+t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68
+t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5
+t271.5 -112.5t112.5 -271.5z" />
+    <glyph glyph-name="stethoscope" unicode="&#xf0f1;" horiz-adv-x="1408" 
+d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48
+t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252
+t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" />
+    <glyph glyph-name="suitcase" unicode="&#xf0f2;" horiz-adv-x="1792" 
+d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66
+t66 -158z" />
+    <glyph glyph-name="bell_alt" unicode="&#xf0f3;" horiz-adv-x="1792" 
+d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5
+t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
+    <glyph glyph-name="coffee" unicode="&#xf0f4;" horiz-adv-x="1920" 
+d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45
+t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" />
+    <glyph glyph-name="food" unicode="&#xf0f5;" horiz-adv-x="1408" 
+d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45
+t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="file_text_alt" unicode="&#xf0f6;" 
+d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
+M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704
+q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z" />
+    <glyph glyph-name="building" unicode="&#xf0f7;" horiz-adv-x="1408" 
+d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="hospital" unicode="&#xf0f8;" horiz-adv-x="1408" 
+d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
+M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5
+t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320
+v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="ambulance" unicode="&#xf0f9;" horiz-adv-x="1920" 
+d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5
+t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152
+q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="medkit" unicode="&#xf0fa;" horiz-adv-x="1792" 
+d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32
+q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" />
+    <glyph glyph-name="fighter_jet" unicode="&#xf0fb;" horiz-adv-x="1920" 
+d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96
+q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q128 -28 200 -52t80 -34z" />
+    <glyph glyph-name="beer" unicode="&#xf0fc;" horiz-adv-x="1664" 
+d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" />
+    <glyph glyph-name="h_sign" unicode="&#xf0fd;" 
+d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960
+q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="f0fe" unicode="&#xf0fe;" 
+d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960
+q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="double_angle_left" unicode="&#xf100;" horiz-adv-x="1024" 
+d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23
+t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" />
+    <glyph glyph-name="double_angle_right" unicode="&#xf101;" horiz-adv-x="1024" 
+d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23
+l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
+    <glyph glyph-name="double_angle_up" unicode="&#xf102;" horiz-adv-x="1152" 
+d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393
+q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
+    <glyph glyph-name="double_angle_down" unicode="&#xf103;" horiz-adv-x="1152" 
+d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23
+t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
+    <glyph glyph-name="angle_left" unicode="&#xf104;" horiz-adv-x="640" 
+d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
+    <glyph glyph-name="angle_right" unicode="&#xf105;" horiz-adv-x="640" 
+d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
+    <glyph glyph-name="angle_up" unicode="&#xf106;" horiz-adv-x="1152" 
+d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
+    <glyph glyph-name="angle_down" unicode="&#xf107;" horiz-adv-x="1152" 
+d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
+    <glyph glyph-name="desktop" unicode="&#xf108;" horiz-adv-x="1920" 
+d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19
+t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="laptop" unicode="&#xf109;" horiz-adv-x="1920" 
+d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z
+M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" />
+    <glyph glyph-name="tablet" unicode="&#xf10a;" horiz-adv-x="1152" 
+d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832
+q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="mobile_phone" unicode="&#xf10b;" horiz-adv-x="768" 
+d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136
+q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="circle_blank" unicode="&#xf10c;" 
+d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103
+t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="quote_left" unicode="&#xf10d;" horiz-adv-x="1664" 
+d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z
+M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" />
+    <glyph glyph-name="quote_right" unicode="&#xf10e;" horiz-adv-x="1664" 
+d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216
+v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" />
+    <glyph glyph-name="spinner" unicode="&#xf110;" horiz-adv-x="1792" 
+d="M526 142q0 -53 -37.5 -90.5t-90.5 -37.5q-52 0 -90 38t-38 90q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 -64q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -53 -37.5 -90.5t-90.5 -37.5
+t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1522 142q0 -52 -38 -90t-90 -38q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM558 1138q0 -66 -47 -113t-113 -47t-113 47t-47 113t47 113t113 47t113 -47t47 -113z
+M1728 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1088 1344q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1618 1138q0 -93 -66 -158.5t-158 -65.5q-93 0 -158.5 65.5t-65.5 158.5
+q0 92 65.5 158t158.5 66q92 0 158 -66t66 -158z" />
+    <glyph glyph-name="circle" unicode="&#xf111;" 
+d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="reply" unicode="&#xf112;" horiz-adv-x="1792" 
+d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19
+l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" />
+    <glyph glyph-name="github_alt" unicode="&#xf113;" horiz-adv-x="1664" 
+d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320
+q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86
+t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218
+q0 -87 -27 -168q136 -160 136 -398z" />
+    <glyph glyph-name="folder_close_alt" unicode="&#xf114;" horiz-adv-x="1664" 
+d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320
+q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
+    <glyph glyph-name="folder_open_alt" unicode="&#xf115;" horiz-adv-x="1920" 
+d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68
+v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z
+" />
+    <glyph glyph-name="expand_alt" unicode="&#xf116;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="collapse_alt" unicode="&#xf117;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="smile" unicode="&#xf118;" 
+d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
+t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5
+t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="frown" unicode="&#xf119;" 
+d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
+t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204
+t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="meh" unicode="&#xf11a;" 
+d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
+t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640
+q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="gamepad" unicode="&#xf11b;" horiz-adv-x="1920" 
+d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5
+t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150
+t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" />
+    <glyph glyph-name="keyboard" unicode="&#xf11c;" horiz-adv-x="1920" 
+d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16
+h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16
+h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96
+q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896
+h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" />
+    <glyph glyph-name="flag_alt" unicode="&#xf11d;" horiz-adv-x="1792" 
+d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9
+h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102
+q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
+    <glyph glyph-name="flag_checkered" unicode="&#xf11e;" horiz-adv-x="1792" 
+d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2
+q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266
+q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8
+q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
+    <glyph glyph-name="terminal" unicode="&#xf120;" horiz-adv-x="1664" 
+d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9
+t9 -23z" />
+    <glyph glyph-name="code" unicode="&#xf121;" horiz-adv-x="1920" 
+d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5
+l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" />
+    <glyph glyph-name="reply_all" unicode="&#xf122;" horiz-adv-x="1792" 
+d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1
+q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" />
+    <glyph glyph-name="star_half_empty" unicode="&#xf123;" horiz-adv-x="1664" 
+d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5
+l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" />
+    <glyph glyph-name="location_arrow" unicode="&#xf124;" horiz-adv-x="1408" 
+d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" />
+    <glyph glyph-name="crop" unicode="&#xf125;" horiz-adv-x="1664" 
+d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23
+v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="code_fork" unicode="&#xf126;" horiz-adv-x="1024" 
+d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5
+q-2 -287 -226 -414q-67 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497
+q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" />
+    <glyph glyph-name="unlink" unicode="&#xf127;" horiz-adv-x="1664" 
+d="M439 265l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320
+q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18
+l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9
+t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
+    <glyph glyph-name="question" unicode="&#xf128;" horiz-adv-x="1024" 
+d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5
+t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" />
+    <glyph glyph-name="_279" unicode="&#xf129;" horiz-adv-x="640" 
+d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192
+q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="exclamation" unicode="&#xf12a;" horiz-adv-x="640" 
+d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" />
+    <glyph glyph-name="superscript" unicode="&#xf12b;" 
+d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z
+M1534 846v-206h-514l-3 27q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5
+t-65.5 -51.5t-30.5 -63h232v80h126z" />
+    <glyph glyph-name="subscript" unicode="&#xf12c;" 
+d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z
+M1536 -50v-206h-514l-4 27q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73
+h232v80h126z" />
+    <glyph glyph-name="_283" unicode="&#xf12d;" horiz-adv-x="1920" 
+d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" />
+    <glyph glyph-name="puzzle_piece" unicode="&#xf12e;" horiz-adv-x="1664" 
+d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5
+t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89
+q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117
+q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" />
+    <glyph glyph-name="microphone" unicode="&#xf130;" horiz-adv-x="1152" 
+d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5
+t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" />
+    <glyph glyph-name="microphone_off" unicode="&#xf131;" horiz-adv-x="1408" 
+d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128
+q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23
+t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
+    <glyph glyph-name="shield" unicode="&#xf132;" horiz-adv-x="1280" 
+d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150
+t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="calendar_empty" unicode="&#xf133;" horiz-adv-x="1664" 
+d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280
+q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="fire_extinguisher" unicode="&#xf134;" horiz-adv-x="1408" 
+d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800
+q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113
+q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" />
+    <glyph glyph-name="rocket" unicode="&#xf135;" horiz-adv-x="1664" 
+d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1
+q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" />
+    <glyph glyph-name="maxcdn" unicode="&#xf136;" horiz-adv-x="1792" 
+d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" />
+    <glyph glyph-name="chevron_sign_left" unicode="&#xf137;" 
+d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
+t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="chevron_sign_right" unicode="&#xf138;" 
+d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
+t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="chevron_sign_up" unicode="&#xf139;" 
+d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
+t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="chevron_sign_down" unicode="&#xf13a;" 
+d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
+t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="html5" unicode="&#xf13b;" horiz-adv-x="1408" 
+d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" />
+    <glyph glyph-name="css3" unicode="&#xf13c;" horiz-adv-x="1792" 
+d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" />
+    <glyph glyph-name="anchor" unicode="&#xf13d;" horiz-adv-x="1792" 
+d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352
+q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19
+t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="unlock_alt" unicode="&#xf13e;" horiz-adv-x="1152" 
+d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181
+v-320h736z" />
+    <glyph glyph-name="bullseye" unicode="&#xf140;" 
+d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150
+t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640
+q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="ellipsis_horizontal" unicode="&#xf141;" horiz-adv-x="1408" 
+d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192
+q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
+    <glyph glyph-name="ellipsis_vertical" unicode="&#xf142;" horiz-adv-x="384" 
+d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192
+q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
+    <glyph glyph-name="_303" unicode="&#xf143;" 
+d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 233 -176.5 396.5t-396.5 176.5q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128
+q13 0 23 10t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960
+q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="play_sign" unicode="&#xf144;" 
+d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56
+q16 -8 32 -8q17 0 32 9z" />
+    <glyph glyph-name="ticket" unicode="&#xf145;" horiz-adv-x="1792" 
+d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136
+t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" />
+    <glyph glyph-name="minus_sign_alt" unicode="&#xf146;" 
+d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
+t84.5 -203.5z" />
+    <glyph glyph-name="check_minus" unicode="&#xf147;" horiz-adv-x="1408" 
+d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5
+t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="level_up" unicode="&#xf148;" horiz-adv-x="1024" 
+d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" />
+    <glyph glyph-name="level_down" unicode="&#xf149;" horiz-adv-x="1024" 
+d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" />
+    <glyph glyph-name="check_sign" unicode="&#xf14a;" 
+d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5
+t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="edit_sign" unicode="&#xf14b;" 
+d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120
+v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="_312" unicode="&#xf14c;" 
+d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960
+q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="share_sign" unicode="&#xf14d;" 
+d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q11 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5
+t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="compass" unicode="&#xf14e;" 
+d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
+t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="collapse" unicode="&#xf150;" 
+d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120
+v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="collapse_top" unicode="&#xf151;" 
+d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960
+q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="_317" unicode="&#xf152;" 
+d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5
+t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="eur" unicode="&#xf153;" horiz-adv-x="1024" 
+d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9
+t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26
+l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" />
+    <glyph glyph-name="gbp" unicode="&#xf154;" horiz-adv-x="1024" 
+d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7
+q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" />
+    <glyph glyph-name="usd" unicode="&#xf155;" horiz-adv-x="1024" 
+d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43
+t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5
+t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50
+t53 -63.5t31.5 -76.5t13 -94z" />
+    <glyph glyph-name="inr" unicode="&#xf156;" horiz-adv-x="898" 
+d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102
+q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="jpy" unicode="&#xf157;" horiz-adv-x="1027" 
+d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61
+l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" />
+    <glyph glyph-name="rub" unicode="&#xf158;" horiz-adv-x="1280" 
+d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128
+q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" />
+    <glyph glyph-name="krw" unicode="&#xf159;" horiz-adv-x="1792" 
+d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23
+t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28
+q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="btc" unicode="&#xf15a;" horiz-adv-x="1280" 
+d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164
+l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30
+t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" />
+    <glyph glyph-name="file" unicode="&#xf15b;" 
+d="M1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472zM896 992q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544z" />
+    <glyph glyph-name="file_text" unicode="&#xf15c;" 
+d="M1468 1060q14 -14 28 -36h-472v472q22 -14 36 -28zM992 896h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28zM1152 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704
+q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23z" />
+    <glyph glyph-name="sort_by_alphabet" unicode="&#xf15d;" horiz-adv-x="1664" 
+d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23
+v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162
+l230 -662h70z" />
+    <glyph glyph-name="_329" unicode="&#xf15e;" horiz-adv-x="1664" 
+d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150
+v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248
+v119h121z" />
+    <glyph glyph-name="sort_by_attributes" unicode="&#xf160;" horiz-adv-x="1792" 
+d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832
+q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256
+q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="sort_by_attributes_alt" unicode="&#xf161;" horiz-adv-x="1792" 
+d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192
+q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832
+q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="sort_by_order" unicode="&#xf162;" 
+d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23
+zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5
+t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" />
+    <glyph glyph-name="sort_by_order_alt" unicode="&#xf163;" 
+d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9
+t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13
+q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" />
+    <glyph glyph-name="_334" unicode="&#xf164;" horiz-adv-x="1664" 
+d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76
+q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5
+t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" />
+    <glyph glyph-name="_335" unicode="&#xf165;" horiz-adv-x="1664" 
+d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135
+t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121
+t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" />
+    <glyph glyph-name="youtube_sign" unicode="&#xf166;" 
+d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 17 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15
+q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38
+q21 -29 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5
+q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78q7 -23 23 -69l24 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38
+q-51 0 -78 -38q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5
+h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="youtube" unicode="&#xf167;" 
+d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73
+q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51
+q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99
+q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-38 -51 -106 -51q-67 0 -105 51
+q-28 38 -28 118v175q0 80 28 117q38 51 105 51q68 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" />
+    <glyph glyph-name="xing" unicode="&#xf168;" horiz-adv-x="1408" 
+d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942
+q25 45 64 45h241q22 0 31 -15z" />
+    <glyph glyph-name="xing_sign" unicode="&#xf169;" 
+d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1
+l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="youtube_play" unicode="&#xf16a;" horiz-adv-x="1792" 
+d="M711 408l484 250l-484 253v-503zM896 1270q168 0 324.5 -4.5t229.5 -9.5l73 -4q1 0 17 -1.5t23 -3t23.5 -4.5t28.5 -8t28 -13t31 -19.5t29 -26.5q6 -6 15.5 -18.5t29 -58.5t26.5 -101q8 -64 12.5 -136.5t5.5 -113.5v-40v-136q1 -145 -18 -290q-7 -55 -25 -99.5t-32 -61.5
+l-14 -17q-14 -15 -29 -26.5t-31 -19t-28 -12.5t-28.5 -8t-24 -4.5t-23 -3t-16.5 -1.5q-251 -19 -627 -19q-207 2 -359.5 6.5t-200.5 7.5l-49 4l-36 4q-36 5 -54.5 10t-51 21t-56.5 41q-6 6 -15.5 18.5t-29 58.5t-26.5 101q-8 64 -12.5 136.5t-5.5 113.5v40v136
+q-1 145 18 290q7 55 25 99.5t32 61.5l14 17q14 15 29 26.5t31 19.5t28 13t28.5 8t23.5 4.5t23 3t17 1.5q251 18 627 18z" />
+    <glyph glyph-name="dropbox" unicode="&#xf16b;" horiz-adv-x="1792" 
+d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" />
+    <glyph glyph-name="stackexchange" unicode="&#xf16c;" 
+d="M1289 -96h-1118v480h-160v-640h1438v640h-160v-480zM347 428l33 157l783 -165l-33 -156zM450 802l67 146l725 -339l-67 -145zM651 1158l102 123l614 -513l-102 -123zM1048 1536l477 -641l-128 -96l-477 641zM330 65v159h800v-159h-800z" />
+    <glyph glyph-name="instagram" unicode="&#xf16d;" 
+d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1162 640q0 -164 -115 -279t-279 -115t-279 115t-115 279t115 279t279 115t279 -115t115 -279zM1270 1050q0 -38 -27 -65t-65 -27t-65 27t-27 65t27 65t65 27t65 -27t27 -65zM768 1270
+q-7 0 -76.5 0.5t-105.5 0t-96.5 -3t-103 -10t-71.5 -18.5q-50 -20 -88 -58t-58 -88q-11 -29 -18.5 -71.5t-10 -103t-3 -96.5t0 -105.5t0.5 -76.5t-0.5 -76.5t0 -105.5t3 -96.5t10 -103t18.5 -71.5q20 -50 58 -88t88 -58q29 -11 71.5 -18.5t103 -10t96.5 -3t105.5 0t76.5 0.5
+t76.5 -0.5t105.5 0t96.5 3t103 10t71.5 18.5q50 20 88 58t58 88q11 29 18.5 71.5t10 103t3 96.5t0 105.5t-0.5 76.5t0.5 76.5t0 105.5t-3 96.5t-10 103t-18.5 71.5q-20 50 -58 88t-88 58q-29 11 -71.5 18.5t-103 10t-96.5 3t-105.5 0t-76.5 -0.5zM1536 640q0 -229 -5 -317
+q-10 -208 -124 -322t-322 -124q-88 -5 -317 -5t-317 5q-208 10 -322 124t-124 322q-5 88 -5 317t5 317q10 208 124 322t322 124q88 5 317 5t317 -5q208 -10 322 -124t124 -322q5 -88 5 -317z" />
+    <glyph glyph-name="flickr" unicode="&#xf16e;" 
+d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150
+t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" />
+    <glyph glyph-name="adn" unicode="&#xf170;" 
+d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="f171" unicode="&#xf171;" horiz-adv-x="1408" 
+d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22
+t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18
+t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5
+t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" />
+    <glyph glyph-name="bitbucket_sign" unicode="&#xf172;" 
+d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5
+t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z
+M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120
+v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="tumblr" unicode="&#xf173;" horiz-adv-x="1024" 
+d="M944 207l80 -237q-23 -35 -111 -66t-177 -32q-104 -2 -190.5 26t-142.5 74t-95 106t-55.5 120t-16.5 118v544h-168v215q72 26 129 69.5t91 90t58 102t34 99t15 88.5q1 5 4.5 8.5t7.5 3.5h244v-424h333v-252h-334v-518q0 -30 6.5 -56t22.5 -52.5t49.5 -41.5t81.5 -14
+q78 2 134 29z" />
+    <glyph glyph-name="tumblr_sign" unicode="&#xf174;" 
+d="M1136 75l-62 183q-44 -22 -103 -22q-36 -1 -62 10.5t-38.5 31.5t-17.5 40.5t-5 43.5v398h257v194h-256v326h-188q-8 0 -9 -10q-5 -44 -17.5 -87t-39 -95t-77 -95t-118.5 -68v-165h130v-418q0 -57 21.5 -115t65 -111t121 -85.5t176.5 -30.5q69 1 136.5 25t85.5 50z
+M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="long_arrow_down" unicode="&#xf175;" horiz-adv-x="768" 
+d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" />
+    <glyph glyph-name="long_arrow_up" unicode="&#xf176;" horiz-adv-x="768" 
+d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" />
+    <glyph glyph-name="long_arrow_left" unicode="&#xf177;" horiz-adv-x="1792" 
+d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="long_arrow_right" unicode="&#xf178;" horiz-adv-x="1792" 
+d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" />
+    <glyph glyph-name="apple" unicode="&#xf179;" horiz-adv-x="1408" 
+d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q113 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65
+q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" />
+    <glyph glyph-name="windows" unicode="&#xf17a;" horiz-adv-x="1664" 
+d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" />
+    <glyph glyph-name="android" unicode="&#xf17b;" horiz-adv-x="1408" 
+d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30
+t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5
+h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" />
+    <glyph glyph-name="linux" unicode="&#xf17c;" 
+d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-10 -11 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z
+M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7
+q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15
+q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5
+t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19
+q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63
+q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18q-2 -1 -4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92
+q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152
+q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-6 0 -8 -2t0 -4
+t5 -3q14 -4 18 -31q0 -3 8 2q2 2 2 3zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5
+t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43
+q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49
+t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54
+q110 143 124 195q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5
+t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5
+t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" />
+    <glyph glyph-name="dribble" unicode="&#xf17d;" 
+d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81
+t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19
+q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -5 6.5 -17t7.5 -17q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6
+t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="skype" unicode="&#xf17e;" 
+d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5
+t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5
+q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80
+q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" />
+    <glyph glyph-name="foursquare" unicode="&#xf180;" horiz-adv-x="1280" 
+d="M1000 1102l37 194q5 23 -9 40t-35 17h-712q-23 0 -38.5 -17t-15.5 -37v-1101q0 -7 6 -1l291 352q23 26 38 33.5t48 7.5h239q22 0 37 14.5t18 29.5q24 130 37 191q4 21 -11.5 40t-36.5 19h-294q-29 0 -48 19t-19 48v42q0 29 19 47.5t48 18.5h346q18 0 35 13.5t20 29.5z
+M1227 1324q-15 -73 -53.5 -266.5t-69.5 -350t-35 -173.5q-6 -22 -9 -32.5t-14 -32.5t-24.5 -33t-38.5 -21t-58 -10h-271q-13 0 -22 -10q-8 -9 -426 -494q-22 -25 -58.5 -28.5t-48.5 5.5q-55 22 -55 98v1410q0 55 38 102.5t120 47.5h888q95 0 127 -53t10 -159zM1227 1324
+l-158 -790q4 17 35 173.5t69.5 350t53.5 266.5z" />
+    <glyph glyph-name="trello" unicode="&#xf181;" 
+d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408
+q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="female" unicode="&#xf182;" horiz-adv-x="1280" 
+d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43
+q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
+    <glyph glyph-name="male" unicode="&#xf183;" horiz-adv-x="1024" 
+d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z
+M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
+    <glyph glyph-name="gittip" unicode="&#xf184;" 
+d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
+t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="sun" unicode="&#xf185;" horiz-adv-x="1792" 
+d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4
+l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94
+q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" />
+    <glyph glyph-name="_366" unicode="&#xf186;" 
+d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61
+t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" />
+    <glyph glyph-name="archive" unicode="&#xf187;" horiz-adv-x="1792" 
+d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536
+q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="bug" unicode="&#xf188;" horiz-adv-x="1664" 
+d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207
+q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19
+t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" />
+    <glyph glyph-name="vk" unicode="&#xf189;" horiz-adv-x="1920" 
+d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-40 -51 -55 -72t-30.5 -49.5t-12 -42t13 -34.5t32.5 -43t57 -53q4 -2 5 -4q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58
+t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6
+q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q16 19 38 30q53 26 239 24
+q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2
+q39 5 64 -2.5t31 -16.5z" />
+    <glyph glyph-name="weibo" unicode="&#xf18a;" horiz-adv-x="1792" 
+d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12
+q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422
+q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178
+q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z
+M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" />
+    <glyph glyph-name="renren" unicode="&#xf18b;" 
+d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495
+q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" />
+    <glyph glyph-name="_372" unicode="&#xf18c;" horiz-adv-x="1408" 
+d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5
+t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56
+t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -4 1 -50t-1 -72q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5
+t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" />
+    <glyph glyph-name="stack_exchange" unicode="&#xf18d;" horiz-adv-x="1280" 
+d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z
+" />
+    <glyph glyph-name="_374" unicode="&#xf18e;" 
+d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198
+t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="arrow_circle_alt_left" unicode="&#xf190;" 
+d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198
+t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="_376" unicode="&#xf191;" 
+d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z
+M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="dot_circle_alt" unicode="&#xf192;" 
+d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5
+t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="_378" unicode="&#xf193;" horiz-adv-x="1664" 
+d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128
+q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 17 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" />
+    <glyph glyph-name="vimeo_square" unicode="&#xf194;" 
+d="M1292 898q10 216 -161 222q-231 8 -312 -261q44 19 82 19q85 0 74 -96q-4 -57 -74 -167t-105 -110q-43 0 -82 169q-13 54 -45 255q-30 189 -160 177q-59 -7 -164 -100l-81 -72l-81 -72l52 -67q76 52 87 52q57 0 107 -179q15 -55 45 -164.5t45 -164.5q68 -179 164 -179
+q157 0 383 294q220 283 226 444zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="_380" unicode="&#xf195;" horiz-adv-x="1152" 
+d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160
+q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="plus_square_o" unicode="&#xf196;" horiz-adv-x="1408" 
+d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832
+q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="_382" unicode="&#xf197;" horiz-adv-x="2176" 
+d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40
+t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29
+q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" />
+    <glyph glyph-name="_383" unicode="&#xf198;" horiz-adv-x="1664" 
+d="M1519 760q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72l-55 163l-153 -53q-29 -9 -50 -9
+q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102
+t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8zM725 498l310 105l-105 315l-310 -107z" />
+    <glyph glyph-name="_384" unicode="&#xf199;" 
+d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM1280 352v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99q-98 -69 -164 -69v0v0q-66 0 -164 69
+q-47 32 -142 92.5t-142 92.5q-12 8 -33 27t-31 27v-436q0 -40 28 -68t68 -28h832q40 0 68 28t28 68zM1280 925q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13
+t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5z" />
+    <glyph glyph-name="_385" unicode="&#xf19a;" horiz-adv-x="1792" 
+d="M127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM1415 679q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15t-1.5 -18.5t9 -16.5
+t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21
+t14.5 -24t14 -23q63 -107 63 -212zM909 573l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1570 1009q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5l235 678q59 169 59 276q0 42 -6 79zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286
+t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 -215q173 0 331.5 68t273 182.5t182.5 273t68 331.5t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5t68 -331.5t182.5 -273
+t273 -182.5t331.5 -68z" />
+    <glyph glyph-name="_386" unicode="&#xf19b;" horiz-adv-x="1792" 
+d="M1086 1536v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360zM1755 954l37 -390l-525 114l147 83q-119 70 -280 99v172q277 -33 481 -157z" />
+    <glyph glyph-name="_387" unicode="&#xf19c;" horiz-adv-x="2048" 
+d="M960 1536l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664v64q0 26 20.5 45t48.5 19h59v768zM1851 -64
+q28 0 48.5 -19t20.5 -45v-128h-1920v128q0 26 20.5 45t48.5 19h1782z" />
+    <glyph glyph-name="_388" unicode="&#xf19d;" horiz-adv-x="2304" 
+d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433
+q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" />
+    <glyph glyph-name="_389" unicode="&#xf19e;" 
+d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q44 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0
+q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" />
+    <glyph glyph-name="uniF1A0" unicode="&#xf1a0;" 
+d="M768 750h725q12 -67 12 -128q0 -217 -91 -387.5t-259.5 -266.5t-386.5 -96q-157 0 -299 60.5t-245 163.5t-163.5 245t-60.5 299t60.5 299t163.5 245t245 163.5t299 60.5q300 0 515 -201l-209 -201q-123 119 -306 119q-129 0 -238.5 -65t-173.5 -176.5t-64 -243.5
+t64 -243.5t173.5 -176.5t238.5 -65q87 0 160 24t120 60t82 82t51.5 87t22.5 78h-436v264z" />
+    <glyph glyph-name="f1a1" unicode="&#xf1a1;" horiz-adv-x="1792" 
+d="M1095 369q16 -16 0 -31q-62 -62 -199 -62t-199 62q-16 15 0 31q6 6 15 6t15 -6q48 -49 169 -49q120 0 169 49q6 6 15 6t15 -6zM788 550q0 -37 -26 -63t-63 -26t-63.5 26t-26.5 63q0 38 26.5 64t63.5 26t63 -26.5t26 -63.5zM1183 550q0 -37 -26.5 -63t-63.5 -26t-63 26
+t-26 63t26 63.5t63 26.5t63.5 -26t26.5 -64zM1434 670q0 49 -35 84t-85 35t-86 -36q-130 90 -311 96l63 283l200 -45q0 -37 26 -63t63 -26t63.5 26.5t26.5 63.5t-26.5 63.5t-63.5 26.5q-54 0 -80 -50l-221 49q-19 5 -25 -16l-69 -312q-180 -7 -309 -97q-35 37 -87 37
+q-50 0 -85 -35t-35 -84q0 -35 18.5 -64t49.5 -44q-6 -27 -6 -56q0 -142 140 -243t337 -101q198 0 338 101t140 243q0 32 -7 57q30 15 48 43.5t18 63.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191
+t348 71t348 -71t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="_392" unicode="&#xf1a2;" 
+d="M939 407q13 -13 0 -26q-53 -53 -171 -53t-171 53q-13 13 0 26q5 6 13 6t13 -6q42 -42 145 -42t145 42q5 6 13 6t13 -6zM676 563q0 -31 -23 -54t-54 -23t-54 23t-23 54q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1014 563q0 -31 -23 -54t-54 -23t-54 23t-23 54
+q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1229 666q0 42 -30 72t-73 30q-42 0 -73 -31q-113 78 -267 82l54 243l171 -39q1 -32 23.5 -54t53.5 -22q32 0 54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5q-48 0 -69 -43l-189 42q-17 5 -21 -13l-60 -268q-154 -6 -265 -83
+q-30 32 -74 32q-43 0 -73 -30t-30 -72q0 -30 16 -55t42 -38q-5 -25 -5 -48q0 -122 120 -208.5t289 -86.5q170 0 290 86.5t120 208.5q0 25 -6 49q25 13 40.5 37.5t15.5 54.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960
+q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="_393" unicode="&#xf1a3;" 
+d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150
+v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103
+t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="f1a4" unicode="&#xf1a4;" horiz-adv-x="1920" 
+d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328
+v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" />
+    <glyph glyph-name="_395" unicode="&#xf1a5;" 
+d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
+t84.5 -203.5z" />
+    <glyph glyph-name="_396" unicode="&#xf1a6;" horiz-adv-x="2048" 
+d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968v-697h205v697h-205zM614 1254v-204h205v204h-205zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123
+v-369h123z" />
+    <glyph glyph-name="_397" unicode="&#xf1a7;" 
+d="M1046 516q0 -64 -38 -109t-91 -45q-43 0 -70 15v277q28 17 70 17q53 0 91 -45.5t38 -109.5zM703 944q0 -64 -38 -109.5t-91 -45.5q-43 0 -70 15v277q28 17 70 17q53 0 91 -45t38 -109zM1265 513q0 134 -88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101
+v-636l211 41v206q51 -19 117 -19q125 0 213 95t88 229zM922 940q0 134 -88.5 229t-213.5 95q-74 0 -141 -36h-186v-840l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960
+q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="_398" unicode="&#xf1a8;" horiz-adv-x="2038" 
+d="M1222 607q75 3 143.5 -20.5t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14
+q6 -5 28 -23.5t25.5 -22t19 -18t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24
+q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33
+q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5
+t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5zM1282 842q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43
+q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5
+t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM822 568l48 12l109 -177l-73 -48zM1323 51q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13
+t-54 -9.5t-53.5 -7.5t-32 -4.5l-7 43q21 2 60.5 8.5t72 10t60.5 3.5h14zM866 679l-96 -20l-6 17q10 1 32.5 7t34.5 6q19 0 35 -10zM1061 45h31l10 -83l-41 -12v95zM1950 1535v1v-1zM1950 1535l-1 -5l-2 -2l1 3zM1950 1535l1 1z" />
+    <glyph glyph-name="_399" unicode="&#xf1a9;" 
+d="M1167 -50q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16t7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29zM1128 65q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10
+q-29 -12 -78 -56q-26 -24 -12 -44q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34zM1483 346q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14
+q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14
+t55.5 63q28 41 42.5 101t14.5 106zM1536 506q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44
+q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5t19.5 -177.5z" />
+    <glyph glyph-name="_400" unicode="&#xf1aa;" 
+d="M1070 463l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5t-60 145.5q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160z
+M729 1145l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5q-70 15 -115 71t-45 129q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5
+t149.5 -87.5zM1536 78q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5
+q76 -11 126.5 -68.5t50.5 -134.5zM1534 1202q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152l-160 -160l-152 152l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126
+t135.5 51q85 0 145 -60.5t60 -145.5z" />
+    <glyph glyph-name="f1ab" unicode="&#xf1ab;" 
+d="M654 458q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110q-4 -2 -19.5 -4t-18.5 0q6 4 82 92q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5
+q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28
+q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5zM449 944q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032l-694 -233v-1031z
+M1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11
+q73 -37 159.5 -61.5t157.5 -24.5q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5zM1536 1050v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3v1078q3 9 4 10q5 6 20 11q107 36 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5
+q20 0 20 -21v-418z" />
+    <glyph glyph-name="_402" unicode="&#xf1ac;" horiz-adv-x="1792" 
+d="M288 1152q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h128zM1664 989q58 -34 93 -93t35 -128v-768q0 -106 -75 -181t-181 -75h-864q-66 0 -113 47t-47 113v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48
+l152 -152q28 -28 48 -76t20 -88v-163zM928 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 512v128q0 14 -9 23
+t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128
+q14 0 23 9t9 23zM1184 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 256v128q0 14 -9 23t-23 9h-128
+q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1536 896v256h-160q-40 0 -68 28t-28 68v160h-640v-512h896z" />
+    <glyph glyph-name="_403" unicode="&#xf1ad;" 
+d="M1344 1536q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280zM512 1248v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 992v-64q0 -14 9 -23t23 -9h64q14 0 23 9
+t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 736v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 480v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 160v64
+q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64
+q14 0 23 9t9 23zM384 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 -96v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9
+t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM896 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 928v64
+q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 160v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64
+q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9
+t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23z" />
+    <glyph glyph-name="_404" unicode="&#xf1ae;" horiz-adv-x="1280" 
+d="M1188 988l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68t28 68q29 28 68.5 28t67.5 -28l228 -228h368l228 228q28 28 68 28t68 -28q28 -29 28 -68.5t-28 -67.5zM864 1152
+q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
+    <glyph glyph-name="uniF1B1" unicode="&#xf1b0;" horiz-adv-x="1664" 
+d="M780 1064q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5zM438 581q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152q0 80 42 139.5t119 59.5
+q76 0 141.5 -55.5t100.5 -134t35 -152.5zM832 608q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146q0 86 56 191.5t139.5 192.5t187.5 146t193 59zM1071 819
+q-61 0 -105 39t-63 92.5t-19 113.5q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5zM1503 923q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5q-77 0 -119 59t-42 139q0 74 35 152.5
+t100.5 134t141.5 55.5z" />
+    <glyph glyph-name="_406" unicode="&#xf1b1;" horiz-adv-x="768" 
+d="M704 1008q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5z" />
+    <glyph glyph-name="_407" unicode="&#xf1b2;" horiz-adv-x="1792" 
+d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73z
+" />
+    <glyph glyph-name="_408" unicode="&#xf1b3;" horiz-adv-x="2304" 
+d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416q0 -36 -19 -67
+t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-4 2 -7 4q-2 -2 -7 -4l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70
+v-400l434 -186q36 -16 57 -48t21 -70z" />
+    <glyph glyph-name="_409" unicode="&#xf1b4;" horiz-adv-x="2048" 
+d="M1848 1197h-511v-124h511v124zM1596 771q-90 0 -146 -52.5t-62 -142.5h408q-18 195 -200 195zM1612 186q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658
+q0 -111 57.5 -171.5t166.5 -60.5zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5t45.5 113.5q0 144 -190 144h-260v-294zM0 1282h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204
+q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611v1260z" />
+    <glyph glyph-name="_410" unicode="&#xf1b5;" 
+d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM499 1041h-371v-787h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5
+t-56.5 60.5t-79 29.5t-97 8.5zM477 723h-176v184h163q119 0 119 -90q0 -94 -106 -94zM486 388h-185v217h189q124 0 124 -113q0 -104 -128 -104zM1136 356q-68 0 -104 38t-36 107h411q1 10 1 30q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216q0 -135 79 -217
+t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20zM1126 722q113 0 124 -122h-254q4 56 39 89t91 33zM964 988h319v-77h-319v77z" />
+    <glyph glyph-name="_411" unicode="&#xf1b6;" horiz-adv-x="1792" 
+d="M1582 954q0 -101 -71.5 -172.5t-172.5 -71.5t-172.5 71.5t-71.5 172.5t71.5 172.5t172.5 71.5t172.5 -71.5t71.5 -172.5zM812 212q0 104 -73 177t-177 73q-27 0 -54 -6l104 -42q77 -31 109.5 -106.5t1.5 -151.5q-31 -77 -107 -109t-152 -1q-21 8 -62 24.5t-61 24.5
+q32 -60 91 -96.5t130 -36.5q104 0 177 73t73 177zM1642 953q0 126 -89.5 215.5t-215.5 89.5q-127 0 -216.5 -89.5t-89.5 -215.5q0 -127 89.5 -216t216.5 -89q126 0 215.5 89t89.5 216zM1792 953q0 -189 -133.5 -322t-321.5 -133l-437 -319q-12 -129 -109 -218t-229 -89
+q-121 0 -214 76t-118 192l-230 92v429l389 -157q79 48 173 48q13 0 35 -2l284 407q2 187 135.5 319t320.5 132q188 0 321.5 -133.5t133.5 -321.5z" />
+    <glyph glyph-name="_412" unicode="&#xf1b7;" 
+d="M1242 889q0 80 -57 136.5t-137 56.5t-136.5 -57t-56.5 -136q0 -80 56.5 -136.5t136.5 -56.5t137 56.5t57 136.5zM632 301q0 -83 -58 -140.5t-140 -57.5q-56 0 -103 29t-72 77q52 -20 98 -40q60 -24 120 1.5t85 86.5q24 60 -1.5 120t-86.5 84l-82 33q22 5 42 5
+q82 0 140 -57.5t58 -140.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v153l172 -69q20 -92 93.5 -152t168.5 -60q104 0 181 70t87 173l345 252q150 0 255.5 105.5t105.5 254.5q0 150 -105.5 255.5t-255.5 105.5
+q-148 0 -253 -104.5t-107 -252.5l-225 -322q-9 1 -28 1q-75 0 -137 -37l-297 119v468q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5zM1289 887q0 -100 -71 -170.5t-171 -70.5t-170.5 70.5t-70.5 170.5t70.5 171t170.5 71q101 0 171.5 -70.5t70.5 -171.5z
+" />
+    <glyph glyph-name="_413" unicode="&#xf1b8;" horiz-adv-x="1792" 
+d="M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188
+l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5
+t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1
+q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z" />
+    <glyph glyph-name="_414" unicode="&#xf1b9;" horiz-adv-x="2048" 
+d="M480 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM516 768h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5zM1888 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM2048 544v-384
+q0 -14 -9 -23t-23 -9h-96v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-1024v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h768q98 0 179 -63.5t104 -157.5
+l105 -419h28q93 0 158.5 -65.5t65.5 -158.5z" />
+    <glyph glyph-name="_415" unicode="&#xf1ba;" horiz-adv-x="2048" 
+d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5
+t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z
+M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" />
+    <glyph glyph-name="_416" unicode="&#xf1bb;" 
+d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384
+q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" />
+    <glyph glyph-name="_417" unicode="&#xf1bc;" 
+d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64
+q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37
+q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="_418" unicode="&#xf1bd;" horiz-adv-x="1024" 
+d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273l-30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273l30 30h301v-303z" />
+    <glyph glyph-name="_419" unicode="&#xf1be;" horiz-adv-x="2304" 
+d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11
+q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245
+q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785
+l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242
+q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236
+q0 -11 -8 -19t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786
+q-13 2 -22 11t-9 22v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" />
+    <glyph glyph-name="uniF1C0" unicode="&#xf1c0;" 
+d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127
+t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5
+t-103 128v128q0 69 103 128t280 93.5t385 34.5z" />
+    <glyph glyph-name="uniF1C1" unicode="&#xf1c1;" 
+d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
+M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197
+q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8
+q-1 1 -1 2q-1 2 -1 3q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" />
+    <glyph glyph-name="_422" unicode="&#xf1c2;" 
+d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
+M233 768v-107h70l164 -661h159l128 485q7 20 10 46q2 16 2 24h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4q0 3 -0.5 6.5t-1.5 8t-1 6.5q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5
+t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300z" />
+    <glyph glyph-name="_423" unicode="&#xf1c3;" 
+d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
+M429 106v-106h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107
+h-290v-107h68l189 -272l-194 -283h-68z" />
+    <glyph glyph-name="_424" unicode="&#xf1c4;" 
+d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
+M416 106v-106h327v106h-93v167h137q76 0 118 15q67 23 106.5 87t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92zM769 386h-119v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15z" />
+    <glyph glyph-name="_425" unicode="&#xf1c5;" 
+d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
+M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z" />
+    <glyph glyph-name="_426" unicode="&#xf1c6;" 
+d="M640 1152v128h-128v-128h128zM768 1024v128h-128v-128h128zM640 896v128h-128v-128h128zM768 768v128h-128v-128h128zM1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400
+v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536h1280zM781 593l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5q0 25 8 52q21 63 120 396v128h128v-128h79
+q22 0 39 -13t23 -34zM640 128q53 0 90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45t37.5 -45t90.5 -19z" />
+    <glyph glyph-name="_427" unicode="&#xf1c7;" 
+d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
+M620 686q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h131l166 167q16 15 35 7zM1037 -3q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5
+q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5t23.5 -42.5q18 -15 40 -15zM826 145q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5t20 -44.5q20 -17 44 -17z" />
+    <glyph glyph-name="_428" unicode="&#xf1c8;" 
+d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
+M768 768q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h384zM1260 766q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9l-265 266v90l265 266q9 9 23 9q4 0 12 -2z" />
+    <glyph glyph-name="_429" unicode="&#xf1c9;" 
+d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
+M480 768q8 11 21 12.5t24 -6.5l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5l-226 301q-14 19 0 38zM1282 467q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21t6.5 24l182 243
+l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5zM662 6q-13 2 -20.5 13t-5.5 24l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5z" />
+    <glyph glyph-name="_430" unicode="&#xf1ca;" 
+d="M1497 709v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406
+q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z" />
+    <glyph glyph-name="_431" unicode="&#xf1cb;" horiz-adv-x="1792" 
+d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546
+q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64z" />
+    <glyph glyph-name="_432" unicode="&#xf1cc;" horiz-adv-x="2048" 
+d="M1800 764q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94
+q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55
+t121.5 -21q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97l93 -108q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z" />
+    <glyph glyph-name="_433" unicode="&#xf1cd;" horiz-adv-x="1792" 
+d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 1408q-190 0 -361 -90l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90zM218 279l194 194
+q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361t90 -361zM896 -128q190 0 361 90l-194 194q-82 -28 -167 -28t-167 28l-194 -194q171 -90 361 -90zM896 256q159 0 271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5
+t271.5 -112.5zM1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" />
+    <glyph glyph-name="_434" unicode="&#xf1ce;" horiz-adv-x="1792" 
+d="M1760 640q0 -176 -68.5 -336t-184 -275.5t-275.5 -184t-336 -68.5t-336 68.5t-275.5 184t-184 275.5t-68.5 336q0 213 97 398.5t265 305.5t374 151v-228q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5
+t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v228q206 -31 374 -151t265 -305.5t97 -398.5z" />
+    <glyph glyph-name="uniF1D0" unicode="&#xf1d0;" horiz-adv-x="1792" 
+d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41
+t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170
+t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136
+q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" />
+    <glyph glyph-name="uniF1D1" unicode="&#xf1d1;" horiz-adv-x="1792" 
+d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251
+l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162
+q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33
+q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5
+t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71
+t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="uniF1D2" unicode="&#xf1d2;" 
+d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85
+q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392
+q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24zM924 1072
+q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="_438" unicode="&#xf1d3;" horiz-adv-x="1792" 
+d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58
+q0 -31 22.5 -51.5t58 -32t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47
+q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171
+v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" />
+    <glyph glyph-name="_439" unicode="&#xf1d4;" 
+d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="uniF1D5" unicode="&#xf1d5;" horiz-adv-x="1280" 
+d="M842 964q0 -80 -57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5
+t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153
+t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" />
+    <glyph glyph-name="uniF1D6" unicode="&#xf1d6;" horiz-adv-x="1792" 
+d="M270 730q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5t3.5 -5t2 -3.5
+q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9t-98 20
+t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20q-18 -41 -54.5 -74.5
+t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" />
+    <glyph glyph-name="uniF1D7" unicode="&#xf1d7;" horiz-adv-x="2048" 
+d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25
+q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5
+q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109
+q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" />
+    <glyph glyph-name="_443" unicode="&#xf1d8;" horiz-adv-x="1792" 
+d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11z" />
+    <glyph glyph-name="_444" unicode="&#xf1d9;" horiz-adv-x="1792" 
+d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55q-3 39 32 59l1664 960q35 21 68 -2zM1422 26l221 1323l-1434 -827l336 -137
+l863 639l-478 -797z" />
+    <glyph glyph-name="_445" unicode="&#xf1da;" 
+d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5
+t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23
+t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="_446" unicode="&#xf1db;" 
+d="M768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
+t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="_447" unicode="&#xf1dc;" horiz-adv-x="1792" 
+d="M1682 -128q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5t45 -15
+t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18q-15 10 -45 12t-53 2
+t-41 14t-18 45q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160
+q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5
+q0 -26 -12 -48t-36 -22z" />
+    <glyph glyph-name="_448" unicode="&#xf1dd;" horiz-adv-x="1280" 
+d="M1278 1347v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179
+q-64 117 -64 259q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43z" />
+    <glyph glyph-name="_449" unicode="&#xf1de;" 
+d="M352 128v-128h-352v128h352zM704 256q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280q26 0 45 -19t19 -45v-256
+q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1216 768q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" />
+    <glyph glyph-name="uniF1E0" unicode="&#xf1e0;" 
+d="M1216 512q133 0 226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5
+t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86z" />
+    <glyph glyph-name="_451" unicode="&#xf1e1;" 
+d="M1280 341q0 88 -62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5t62.5 -150.5
+t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5t150.5 62.5t62.5 150.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="_452" unicode="&#xf1e2;" horiz-adv-x="1792" 
+d="M571 947q-10 25 -34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49t35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49zM1513 1303l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5
+t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68zM1521 1359q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23t9 23q10 9 23 9t23 -9l90 -91
+q10 -9 10 -22.5t-10 -22.5zM1751 1129q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5t10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23zM1792 1312q0 -14 -9 -23t-23 -9h-96q-14 0 -23 9t-9 23t9 23t23 9h96q14 0 23 -9t9 -23zM1600 1504v-96q0 -14 -9 -23t-23 -9
+t-23 9t-9 23v96q0 14 9 23t23 9t23 -9t9 -23zM1751 1449l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5t10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
+    <glyph glyph-name="_453" unicode="&#xf1e3;" horiz-adv-x="1792" 
+d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM1515 186q149 203 149 454v3l-102 -89l-240 224l63 323
+l134 -12q-150 206 -389 282l53 -124l-287 -159l-287 159l53 124q-239 -76 -389 -282l135 12l62 -323l-240 -224l-102 89v-3q0 -251 149 -454l30 132l326 -40l139 -298l-116 -69q117 -39 240 -39t240 39l-116 69l139 298l326 40z" />
+    <glyph glyph-name="_454" unicode="&#xf1e4;" horiz-adv-x="1792" 
+d="M448 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM256 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM832 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23
+v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM66 768q-28 0 -47 19t-19 46v129h514v-129q0 -27 -19 -46t-46 -19h-383zM1216 224v-192q0 -14 -9 -23t-23 -9h-192
+q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1600 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23
+zM1408 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1016v-13h-514v10q0 104 -382 102q-382 -1 -382 -102v-10h-514v13q0 17 8.5 43t34 64t65.5 75.5t110.5 76t160 67.5t224 47.5t293.5 18.5t293 -18.5t224 -47.5
+t160.5 -67.5t110.5 -76t65.5 -75.5t34 -64t8.5 -43zM1792 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 962v-129q0 -27 -19 -46t-46 -19h-384q-27 0 -46 19t-19 46v129h514z" />
+    <glyph glyph-name="_455" unicode="&#xf1e5;" horiz-adv-x="1792" 
+d="M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z
+M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="_456" unicode="&#xf1e6;" horiz-adv-x="1792" 
+d="M1755 1083q37 -38 37 -90.5t-37 -90.5l-401 -400l150 -150l-160 -160q-163 -163 -389.5 -186.5t-411.5 100.5l-362 -362h-181v181l362 362q-124 185 -100.5 411.5t186.5 389.5l160 160l150 -150l400 401q38 37 91 37t90 -37t37 -90.5t-37 -90.5l-400 -401l234 -234
+l401 400q38 37 91 37t90 -37z" />
+    <glyph glyph-name="_457" unicode="&#xf1e7;" horiz-adv-x="1792" 
+d="M873 796q0 -83 -63.5 -142.5t-152.5 -59.5t-152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59t152.5 -59t63.5 -143zM1375 796q0 -83 -63 -142.5t-153 -59.5q-89 0 -152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59q90 0 153 -59t63 -143zM1600 616v667q0 87 -32 123.5
+t-111 36.5h-1112q-83 0 -112.5 -34t-29.5 -126v-673q43 -23 88.5 -40t81 -28t81 -18.5t71 -11t70 -4t58.5 -0.5t56.5 2t44.5 2q68 1 95 -27q6 -6 10 -9q26 -25 61 -51q7 91 118 87q5 0 36.5 -1.5t43 -2t45.5 -1t53 1t54.5 4.5t61 8.5t62 13.5t67 19.5t67.5 27t72 34.5z
+M1763 621q-121 -149 -372 -252q84 -285 -23 -465q-66 -113 -183 -148q-104 -32 -182 15q-86 51 -82 164l-1 326v1q-8 2 -24.5 6t-23.5 5l-1 -338q4 -114 -83 -164q-79 -47 -183 -15q-117 36 -182 150q-105 180 -22 463q-251 103 -372 252q-25 37 -4 63t60 -1q4 -2 11.5 -7
+t10.5 -8v694q0 72 47 123t114 51h1257q67 0 114 -51t47 -123v-694l21 15q39 27 60 1t-4 -63z" />
+    <glyph glyph-name="_458" unicode="&#xf1e8;" horiz-adv-x="1792" 
+d="M896 1102v-434h-145v434h145zM1294 1102v-434h-145v434h145zM1294 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1692 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" />
+    <glyph glyph-name="_459" unicode="&#xf1e9;" 
+d="M773 217v-127q-1 -292 -6 -305q-12 -32 -51 -40q-54 -9 -181.5 38t-162.5 89q-13 15 -17 36q-1 12 4 26q4 10 34 47t181 216q1 0 60 70q15 19 39.5 24.5t49.5 -3.5q24 -10 37.5 -29t12.5 -42zM624 468q-3 -55 -52 -70l-120 -39q-275 -88 -292 -88q-35 2 -54 36
+q-12 25 -17 75q-8 76 1 166.5t30 124.5t56 32q13 0 202 -77q71 -29 115 -47l84 -34q23 -9 35.5 -30.5t11.5 -48.5zM1450 171q-7 -54 -91.5 -161t-135.5 -127q-37 -14 -63 7q-14 10 -184 287l-47 77q-14 21 -11.5 46t19.5 46q35 43 83 26q1 -1 119 -40q203 -66 242 -79.5
+t47 -20.5q28 -22 22 -61zM778 803q5 -102 -54 -122q-58 -17 -114 71l-378 598q-8 35 19 62q41 43 207.5 89.5t224.5 31.5q40 -10 49 -45q3 -18 22 -305.5t24 -379.5zM1440 695q3 -39 -26 -59q-15 -10 -329 -86q-67 -15 -91 -23l1 2q-23 -6 -46 4t-37 32q-30 47 0 87
+q1 1 75 102q125 171 150 204t34 39q28 19 65 2q48 -23 123 -133.5t81 -167.5v-3z" />
+    <glyph glyph-name="_460" unicode="&#xf1ea;" horiz-adv-x="2048" 
+d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19
+t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" />
+    <glyph glyph-name="_461" unicode="&#xf1eb;" horiz-adv-x="2048" 
+d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121
+q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z
+M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" />
+    <glyph glyph-name="_462" unicode="&#xf1ec;" horiz-adv-x="1792" 
+d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5
+t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5
+t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5
+t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z
+M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38
+h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="_463" unicode="&#xf1ed;" 
+d="M1519 890q18 -84 -4 -204q-87 -444 -565 -444h-44q-25 0 -44 -16.5t-24 -42.5l-4 -19l-55 -346l-2 -15q-5 -26 -24.5 -42.5t-44.5 -16.5h-251q-21 0 -33 15t-9 36q9 56 26.5 168t26.5 168t27 167.5t27 167.5q5 37 43 37h131q133 -2 236 21q175 39 287 144q102 95 155 246
+q24 70 35 133q1 6 2.5 7.5t3.5 1t6 -3.5q79 -59 98 -162zM1347 1172q0 -107 -46 -236q-80 -233 -302 -315q-113 -40 -252 -42q0 -1 -90 -1l-90 1q-100 0 -118 -96q-2 -8 -85 -530q-1 -10 -12 -10h-295q-22 0 -36.5 16.5t-11.5 38.5l232 1471q5 29 27.5 48t51.5 19h598
+q34 0 97.5 -13t111.5 -32q107 -41 163.5 -123t56.5 -196z" />
+    <glyph glyph-name="_464" unicode="&#xf1ee;" horiz-adv-x="1792" 
+d="M441 864q33 0 52 -26q266 -364 362 -774h-446q-127 441 -367 749q-12 16 -3 33.5t29 17.5h373zM1000 507q-49 -199 -125 -393q-79 310 -256 594q40 221 44 449q211 -340 337 -650zM1099 1216q235 -324 384.5 -698.5t184.5 -773.5h-451q-41 665 -553 1472h435zM1792 640
+q0 -424 -101 -812q-67 560 -359 1083q-25 301 -106 584q-4 16 5.5 28.5t25.5 12.5h359q21 0 38.5 -13t22.5 -33q115 -409 115 -850z" />
+    <glyph glyph-name="uniF1F0" unicode="&#xf1f0;" horiz-adv-x="2304" 
+d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27
+q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128
+q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="_466" unicode="&#xf1f1;" horiz-adv-x="2304" 
+d="M1119 1195q-128 85 -281 85q-103 0 -197.5 -40.5t-162.5 -108.5t-108.5 -162t-40.5 -197q0 -104 40.5 -198t108.5 -162t162 -108.5t198 -40.5q153 0 281 85q-131 107 -178 265.5t0.5 316.5t177.5 265zM1152 1171q-126 -99 -172 -249.5t-0.5 -300.5t172.5 -249
+q127 99 172.5 249t-0.5 300.5t-172 249.5zM1185 1195q130 -107 177.5 -265.5t0.5 -317t-178 -264.5q128 -85 281 -85q104 0 198 40.5t162 108.5t108.5 162t40.5 198q0 103 -40.5 197t-108.5 162t-162.5 108.5t-197.5 40.5q-153 0 -281 -85zM1926 473h7v3h-17v-3h7v-17h3v17z
+M1955 456h4v20h-5l-6 -13l-6 13h-5v-20h3v15l6 -13h4l5 13v-15zM1947 16v-2h-2h-3v3h3h2v-1zM1947 7h3l-4 5h2l1 1q1 1 1 3t-1 3l-1 1h-3h-6v-13h3v5h1zM685 75q0 19 11 31t30 12q18 0 29 -12.5t11 -30.5q0 -19 -11 -31t-29 -12q-19 0 -30 12t-11 31zM1158 119q30 0 35 -32
+h-70q5 32 35 32zM1514 75q0 19 11 31t29 12t29.5 -12.5t11.5 -30.5q0 -19 -11 -31t-30 -12q-18 0 -29 12t-11 31zM1786 75q0 18 11.5 30.5t29.5 12.5t29.5 -12.5t11.5 -30.5q0 -19 -11.5 -31t-29.5 -12t-29.5 12.5t-11.5 30.5zM1944 3q-2 0 -4 1q-1 0 -3 2t-2 3q-1 2 -1 4
+q0 3 1 4q0 2 2 4l1 1q2 0 2 1q2 1 4 1q3 0 4 -1l4 -2l2 -4v-1q1 -2 1 -3l-1 -1v-3t-1 -1l-1 -2q-2 -2 -4 -2q-1 -1 -4 -1zM599 7h30v85q0 24 -14.5 38.5t-39.5 15.5q-32 0 -47 -24q-14 24 -45 24q-24 0 -39 -20v16h-30v-135h30v75q0 36 33 36q30 0 30 -36v-75h29v75
+q0 36 33 36q30 0 30 -36v-75zM765 7h29v68v67h-29v-16q-17 20 -43 20q-29 0 -48 -20t-19 -51t19 -51t48 -20q28 0 43 20v-17zM943 48q0 34 -47 40l-14 2q-23 4 -23 14q0 15 25 15q23 0 43 -11l12 24q-22 14 -55 14q-26 0 -41 -12t-15 -32q0 -33 47 -39l13 -2q24 -4 24 -14
+q0 -17 -31 -17q-25 0 -45 14l-13 -23q25 -17 58 -17q29 0 45.5 12t16.5 32zM1073 14l-8 25q-13 -7 -26 -7q-19 0 -19 22v61h48v27h-48v41h-30v-41h-28v-27h28v-61q0 -50 47 -50q21 0 36 10zM1159 146q-29 0 -48 -20t-19 -51q0 -32 19.5 -51.5t49.5 -19.5q33 0 55 19l-14 22
+q-18 -15 -39 -15q-34 0 -41 33h101v12q0 32 -18 51.5t-46 19.5zM1318 146q-23 0 -35 -20v16h-30v-135h30v76q0 35 29 35q10 0 18 -4l9 28q-9 4 -21 4zM1348 75q0 -31 19.5 -51t52.5 -20q29 0 48 16l-14 24q-18 -13 -35 -12q-18 0 -29.5 12t-11.5 31t11.5 31t29.5 12
+q19 0 35 -12l14 24q-20 16 -48 16q-33 0 -52.5 -20t-19.5 -51zM1593 7h30v68v67h-30v-16q-15 20 -42 20q-29 0 -48.5 -20t-19.5 -51t19.5 -51t48.5 -20q28 0 42 20v-17zM1726 146q-23 0 -35 -20v16h-29v-135h29v76q0 35 29 35q10 0 18 -4l9 28q-8 4 -21 4zM1866 7h29v68v122
+h-29v-71q-15 20 -43 20t-47.5 -20.5t-19.5 -50.5t19.5 -50.5t47.5 -20.5q29 0 43 20v-17zM1944 27l-2 -1h-3q-2 -1 -4 -3q-3 -1 -3 -4q-1 -2 -1 -6q0 -3 1 -5q0 -2 3 -4q2 -2 4 -3t5 -1q4 0 6 1q0 1 2 2l2 1q1 1 3 4q1 2 1 5q0 4 -1 6q-1 1 -3 4q0 1 -2 2l-2 1q-1 0 -3 0.5
+t-3 0.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="_467" unicode="&#xf1f2;" horiz-adv-x="2304" 
+d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42
+q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604
+v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569
+q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73
+t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" />
+    <glyph glyph-name="f1f3" unicode="&#xf1f3;" horiz-adv-x="2304" 
+d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z
+M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260
+l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279
+v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040
+q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168
+q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5
+t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21
+h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 60t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5
+t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" />
+    <glyph glyph-name="_469" unicode="&#xf1f4;" horiz-adv-x="2304" 
+d="M745 630q0 -37 -25.5 -61.5t-62.5 -24.5q-29 0 -46.5 16t-17.5 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM1530 779q0 -42 -22 -57t-66 -15l-32 -1l17 107q2 11 13 11h18q22 0 35 -2t25 -12.5t12 -30.5zM1881 630q0 -36 -25.5 -61t-61.5 -25q-29 0 -47 16
+t-18 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM513 801q0 59 -38.5 85.5t-100.5 26.5h-160q-19 0 -21 -19l-65 -408q-1 -6 3 -11t10 -5h76q20 0 22 19l18 110q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM822 489l41 261q1 6 -3 11t-10 5h-76
+q-14 0 -17 -33q-27 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q28 0 58 12t48 32q-4 -12 -4 -21q0 -16 13 -16h69q19 0 22 19zM1269 752q0 5 -4 9.5t-9 4.5h-77q-11 0 -18 -10l-106 -156l-44 150q-5 16 -22 16h-75q-5 0 -9 -4.5t-4 -9.5q0 -2 19.5 -59
+t42 -123t23.5 -70q-82 -112 -82 -120q0 -13 13 -13h77q11 0 18 10l255 368q2 2 2 7zM1649 801q0 59 -38.5 85.5t-100.5 26.5h-159q-20 0 -22 -19l-65 -408q-1 -6 3 -11t10 -5h82q12 0 16 13l18 116q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM1958 489
+l41 261q1 6 -3 11t-10 5h-76q-14 0 -17 -33q-26 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q29 0 59 12t47 32q0 -1 -2 -9t-2 -12q0 -16 13 -16h69q19 0 22 19zM2176 898v1q0 14 -13 14h-74q-11 0 -13 -11l-65 -416l-1 -2q0 -5 4 -9.5t10 -4.5h66
+q19 0 21 19zM392 764q-5 -35 -26 -46t-60 -11l-33 -1l17 107q2 11 13 11h19q40 0 58 -11.5t12 -48.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="_470" unicode="&#xf1f5;" horiz-adv-x="2304" 
+d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109
+q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118
+q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151
+q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -188q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31
+q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="_471" unicode="&#xf1f6;" horiz-adv-x="2048" 
+d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5
+l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5
+l418 363q10 8 23.5 7t21.5 -11z" />
+    <glyph glyph-name="_472" unicode="&#xf1f7;" horiz-adv-x="2048" 
+d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128
+q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161
+q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" />
+    <glyph glyph-name="_473" unicode="&#xf1f8;" horiz-adv-x="1408" 
+d="M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704
+q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167
+q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="_474" unicode="&#xf1f9;" 
+d="M1150 462v-109q0 -50 -36.5 -89t-94 -60.5t-118 -32.5t-117.5 -11q-205 0 -342.5 139t-137.5 346q0 203 136 339t339 136q34 0 75.5 -4.5t93 -18t92.5 -34t69 -56.5t28 -81v-109q0 -16 -16 -16h-118q-16 0 -16 16v70q0 43 -65.5 67.5t-137.5 24.5q-140 0 -228.5 -91.5
+t-88.5 -237.5q0 -151 91.5 -249.5t233.5 -98.5q68 0 138 24t70 66v70q0 7 4.5 11.5t10.5 4.5h119q6 0 11 -4.5t5 -11.5zM768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5
+t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="_475" unicode="&#xf1fa;" 
+d="M972 761q0 108 -53.5 169t-147.5 61q-63 0 -124 -30.5t-110 -84.5t-79.5 -137t-30.5 -180q0 -112 53.5 -173t150.5 -61q96 0 176 66.5t122.5 166t42.5 203.5zM1536 640q0 -111 -37 -197t-98.5 -135t-131.5 -74.5t-145 -27.5q-6 0 -15.5 -0.5t-16.5 -0.5q-95 0 -142 53
+q-28 33 -33 83q-52 -66 -131.5 -110t-173.5 -44q-161 0 -249.5 95.5t-88.5 269.5q0 157 66 290t179 210.5t246 77.5q87 0 155 -35.5t106 -99.5l2 19l11 56q1 6 5.5 12t9.5 6h118q5 0 13 -11q5 -5 3 -16l-120 -614q-5 -24 -5 -48q0 -39 12.5 -52t44.5 -13q28 1 57 5.5t73 24
+t77 50t57 89.5t24 137q0 292 -174 466t-466 174q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51q228 0 405 144q11 9 24 8t21 -12l41 -49q8 -12 7 -24q-2 -13 -12 -22q-102 -83 -227.5 -128t-258.5 -45q-156 0 -298 61
+t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q344 0 556 -212t212 -556z" />
+    <glyph glyph-name="_476" unicode="&#xf1fb;" horiz-adv-x="1792" 
+d="M1698 1442q94 -94 94 -226.5t-94 -225.5l-225 -223l104 -104q10 -10 10 -23t-10 -23l-210 -210q-10 -10 -23 -10t-23 10l-105 105l-603 -603q-37 -37 -90 -37h-203l-256 -128l-64 64l128 256v203q0 53 37 90l603 603l-105 105q-10 10 -10 23t10 23l210 210q10 10 23 10
+t23 -10l104 -104l223 225q93 94 225.5 94t226.5 -94zM512 64l576 576l-192 192l-576 -576v-192h192z" />
+    <glyph glyph-name="f1fc" unicode="&#xf1fc;" horiz-adv-x="1792" 
+d="M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5
+t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z" />
+    <glyph glyph-name="_478" unicode="&#xf1fd;" horiz-adv-x="1792" 
+d="M1792 128v-384h-1792v384q45 0 85 14t59 27.5t47 37.5q30 27 51.5 38t56.5 11q24 0 44 -7t31 -15t33 -27q29 -25 47 -38t58 -27t86 -14q45 0 85 14.5t58 27t48 37.5q21 19 32.5 27t31 15t43.5 7q35 0 56.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14t85 14t59 27.5
+t47 37.5q30 27 51.5 38t56.5 11q34 0 55.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14zM1792 448v-192q-24 0 -44 7t-31 15t-33 27q-29 25 -47 38t-58 27t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-22 -19 -33 -27t-31 -15t-44 -7q-35 0 -56.5 11t-51.5 38q-29 25 -47 38
+t-58 27t-86 14q-45 0 -85 -14.5t-58 -27t-48 -37.5q-21 -19 -32.5 -27t-31 -15t-43.5 -7q-35 0 -56.5 11t-51.5 38q-28 24 -47 37.5t-59 27.5t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-30 -27 -51.5 -38t-56.5 -11v192q0 80 56 136t136 56h64v448h256v-448h256v448h256v-448
+h256v448h256v-448h64q80 0 136 -56t56 -136zM512 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1024 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5
+q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1536 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150z" />
+    <glyph glyph-name="_479" unicode="&#xf1fe;" horiz-adv-x="2048" 
+d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" />
+    <glyph glyph-name="_480" unicode="&#xf200;" horiz-adv-x="1792" 
+d="M768 646l546 -546q-106 -108 -247.5 -168t-298.5 -60q-209 0 -385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103v-762zM955 640h773q0 -157 -60 -298.5t-168 -247.5zM1664 768h-768v768q209 0 385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="_481" unicode="&#xf201;" horiz-adv-x="2048" 
+d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435q0 -21 -19.5 -29.5t-35.5 7.5l-121 121l-633 -633q-10 -10 -23 -10t-23 10l-233 233l-416 -416l-192 192l585 585q10 10 23 10t23 -10l233 -233l464 464l-121 121q-16 16 -7.5 35.5t29.5 19.5h435q14 0 23 -9
+t9 -23z" />
+    <glyph glyph-name="_482" unicode="&#xf202;" horiz-adv-x="1792" 
+d="M1292 832q0 -6 10 -41q10 -29 25 -49.5t41 -34t44 -20t55 -16.5q325 -91 325 -332q0 -146 -105.5 -242.5t-254.5 -96.5q-59 0 -111.5 18.5t-91.5 45.5t-77 74.5t-63 87.5t-53.5 103.5t-43.5 103t-39.5 106.5t-35.5 95q-32 81 -61.5 133.5t-73.5 96.5t-104 64t-142 20
+q-96 0 -183 -55.5t-138 -144.5t-51 -185q0 -160 106.5 -279.5t263.5 -119.5q177 0 258 95q56 63 83 116l84 -152q-15 -34 -44 -70l1 -1q-131 -152 -388 -152q-147 0 -269.5 79t-190.5 207.5t-68 274.5q0 105 43.5 206t116 176.5t172 121.5t204.5 46q87 0 159 -19t123.5 -50
+t95 -80t72.5 -99t58.5 -117t50.5 -124.5t50 -130.5t55 -127q96 -200 233 -200q81 0 138.5 48.5t57.5 128.5q0 42 -19 72t-50.5 46t-72.5 31.5t-84.5 27t-87.5 34t-81 52t-65 82t-39 122.5q-3 16 -3 33q0 110 87.5 192t198.5 78q78 -3 120.5 -14.5t90.5 -53.5h-1
+q12 -11 23 -24.5t26 -36t19 -27.5l-129 -99q-26 49 -54 70v1q-23 21 -97 21q-49 0 -84 -33t-35 -83z" />
+    <glyph glyph-name="_483" unicode="&#xf203;" 
+d="M1432 484q0 173 -234 239q-35 10 -53 16.5t-38 25t-29 46.5q0 2 -2 8.5t-3 12t-1 7.5q0 36 24.5 59.5t60.5 23.5q54 0 71 -15h-1q20 -15 39 -51l93 71q-39 54 -49 64q-33 29 -67.5 39t-85.5 10q-80 0 -142 -57.5t-62 -137.5q0 -7 2 -23q16 -96 64.5 -140t148.5 -73
+q29 -8 49 -15.5t45 -21.5t38.5 -34.5t13.5 -46.5v-5q1 -58 -40.5 -93t-100.5 -35q-97 0 -167 144q-23 47 -51.5 121.5t-48 125.5t-54 110.5t-74 95.5t-103.5 60.5t-147 24.5q-101 0 -192 -56t-144 -148t-50 -192v-1q4 -108 50.5 -199t133.5 -147.5t196 -56.5q186 0 279 110
+q20 27 31 51l-60 109q-42 -80 -99 -116t-146 -36q-115 0 -191 87t-76 204q0 105 82 189t186 84q112 0 170 -53.5t104 -172.5q8 -21 25.5 -68.5t28.5 -76.5t31.5 -74.5t38.5 -74t45.5 -62.5t55.5 -53.5t66 -33t80 -13.5q107 0 183 69.5t76 174.5zM1536 1120v-960
+q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="_484" unicode="&#xf204;" horiz-adv-x="2048" 
+d="M1152 640q0 104 -40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM1920 640q0 104 -40.5 198.5
+t-109.5 163.5t-163.5 109.5t-198.5 40.5h-386q119 -90 188.5 -224t69.5 -288t-69.5 -288t-188.5 -224h386q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM2048 640q0 -130 -51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5
+t-136.5 204t-51 248.5t51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5z" />
+    <glyph glyph-name="_485" unicode="&#xf205;" horiz-adv-x="2048" 
+d="M0 640q0 130 51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5t-51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5t-136.5 204t-51 248.5zM1408 128q104 0 198.5 40.5t163.5 109.5
+t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" />
+    <glyph glyph-name="_486" unicode="&#xf206;" horiz-adv-x="2304" 
+d="M762 384h-314q-40 0 -57.5 35t6.5 67l188 251q-65 31 -137 31q-132 0 -226 -94t-94 -226t94 -226t226 -94q115 0 203 72.5t111 183.5zM576 512h186q-18 85 -75 148zM1056 512l288 384h-480l-99 -132q105 -103 126 -252h165zM2176 448q0 132 -94 226t-226 94
+q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94t226 94t94 226zM2304 448q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 97 39.5 183.5t109.5 149.5l-65 98l-353 -469
+q-18 -26 -51 -26h-197q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q114 0 215 -55l137 183h-224q-26 0 -45 19t-19 45t19 45t45 19h384v-128h435l-85 128h-222q-26 0 -45 19t-19 45t19 45t45 19h256q33 0 53 -28l267 -400
+q91 44 192 44q185 0 316.5 -131.5t131.5 -316.5z" />
+    <glyph glyph-name="_487" unicode="&#xf207;" 
+d="M384 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1362 716l-72 384q-5 23 -22.5 37.5t-40.5 14.5
+h-918q-23 0 -40.5 -14.5t-22.5 -37.5l-72 -384q-5 -30 14 -53t49 -23h1062q30 0 49 23t14 53zM1136 1328q0 20 -14 34t-34 14h-640q-20 0 -34 -14t-14 -34t14 -34t34 -14h640q20 0 34 14t14 34zM1536 603v-603h-128v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
+t-37.5 90.5v128h-768v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5v128h-128v603q0 112 25 223l103 454q9 78 97.5 137t230 89t312.5 30t312.5 -30t230 -89t97.5 -137l105 -454q23 -102 23 -223z" />
+    <glyph glyph-name="_488" unicode="&#xf208;" horiz-adv-x="2048" 
+d="M1463 704q0 -35 -25 -60.5t-61 -25.5h-702q-36 0 -61 25.5t-25 60.5t25 60.5t61 25.5h702q36 0 61 -25.5t25 -60.5zM1677 704q0 86 -23 170h-982q-36 0 -61 25t-25 60q0 36 25 61t61 25h908q-88 143 -235 227t-320 84q-177 0 -327.5 -87.5t-238 -237.5t-87.5 -327
+q0 -86 23 -170h982q36 0 61 -25t25 -60q0 -36 -25 -61t-61 -25h-908q88 -143 235.5 -227t320.5 -84q132 0 253 51.5t208 139t139 208t52 253.5zM2048 959q0 -35 -25 -60t-61 -25h-131q17 -85 17 -170q0 -167 -65.5 -319.5t-175.5 -263t-262.5 -176t-319.5 -65.5
+q-246 0 -448.5 133t-301.5 350h-189q-36 0 -61 25t-25 61q0 35 25 60t61 25h132q-17 85 -17 170q0 167 65.5 319.5t175.5 263t262.5 176t320.5 65.5q245 0 447.5 -133t301.5 -350h188q36 0 61 -25t25 -61z" />
+    <glyph glyph-name="_489" unicode="&#xf209;" horiz-adv-x="1280" 
+d="M953 1158l-114 -328l117 -21q165 451 165 518q0 56 -38 56q-57 0 -130 -225zM654 471l33 -88q37 42 71 67l-33 5.5t-38.5 7t-32.5 8.5zM362 1367q0 -98 159 -521q17 10 49 10q15 0 75 -5l-121 351q-75 220 -123 220q-19 0 -29 -17.5t-10 -37.5zM283 608q0 -36 51.5 -119
+t117.5 -153t100 -70q14 0 25.5 13t11.5 27q0 24 -32 102q-13 32 -32 72t-47.5 89t-61.5 81t-62 32q-20 0 -45.5 -27t-25.5 -47zM125 273q0 -41 25 -104q59 -145 183.5 -227t281.5 -82q227 0 382 170q152 169 152 427q0 43 -1 67t-11.5 62t-30.5 56q-56 49 -211.5 75.5
+t-270.5 26.5q-37 0 -49 -11q-12 -5 -12 -35q0 -34 21.5 -60t55.5 -40t77.5 -23.5t87.5 -11.5t85 -4t70 0h23q24 0 40 -19q15 -19 19 -55q-28 -28 -96 -54q-61 -22 -93 -46q-64 -46 -108.5 -114t-44.5 -137q0 -31 18.5 -88.5t18.5 -87.5l-3 -12q-4 -12 -4 -14
+q-137 10 -146 216q-8 -2 -41 -2q2 -7 2 -21q0 -53 -40.5 -89.5t-94.5 -36.5q-82 0 -166.5 78t-84.5 159q0 34 33 67q52 -64 60 -76q77 -104 133 -104q12 0 26.5 8.5t14.5 20.5q0 34 -87.5 145t-116.5 111q-43 0 -70 -44.5t-27 -90.5zM11 264q0 101 42.5 163t136.5 88
+q-28 74 -28 104q0 62 61 123t122 61q29 0 70 -15q-163 462 -163 567q0 80 41 130.5t119 50.5q131 0 325 -581q6 -17 8 -23q6 16 29 79.5t43.5 118.5t54 127.5t64.5 123t70.5 86.5t76.5 36q71 0 112 -49t41 -122q0 -108 -159 -550q61 -15 100.5 -46t58.5 -78t26 -93.5
+t7 -110.5q0 -150 -47 -280t-132 -225t-211 -150t-278 -55q-111 0 -223 42q-149 57 -258 191.5t-109 286.5z" />
+    <glyph glyph-name="_490" unicode="&#xf20a;" horiz-adv-x="2048" 
+d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206
+q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307
+t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14
+t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" />
+    <glyph glyph-name="_491" unicode="&#xf20b;" 
+d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5
+t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="_492" unicode="&#xf20c;" 
+d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55
+q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410
+q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" />
+    <glyph glyph-name="_493" unicode="&#xf20d;" 
+d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960q0 -118 -85 -203t-203 -85h-960q-118 0 -203 85t-85 203v960q0 118 85 203t203 85h960q118 0 203 -85t85 -203z" />
+    <glyph glyph-name="_494" unicode="&#xf20e;" horiz-adv-x="2048" 
+d="M2048 641q0 -21 -13 -36.5t-33 -19.5l-205 -356q3 -9 3 -18q0 -20 -12.5 -35.5t-32.5 -19.5l-193 -337q3 -8 3 -16q0 -23 -16.5 -40t-40.5 -17q-25 0 -41 18h-400q-17 -20 -43 -20t-43 20h-399q-17 -20 -43 -20q-23 0 -40 16.5t-17 40.5q0 8 4 20l-193 335
+q-20 4 -32.5 19.5t-12.5 35.5q0 9 3 18l-206 356q-20 5 -32.5 20.5t-12.5 35.5q0 21 13.5 36.5t33.5 19.5l199 344q0 1 -0.5 3t-0.5 3q0 36 34 51l209 363q-4 10 -4 18q0 24 17 40.5t40 16.5q26 0 44 -21h396q16 21 43 21t43 -21h398q18 21 44 21q23 0 40 -16.5t17 -40.5
+q0 -6 -4 -18l207 -358q23 -1 39 -17.5t16 -38.5q0 -13 -7 -27l187 -324q19 -4 31.5 -19.5t12.5 -35.5zM1063 -158h389l-342 354h-143l-342 -354h360q18 16 39 16t39 -16zM112 654q1 -4 1 -13q0 -10 -2 -15l208 -360l15 -6l188 199v347l-187 194q-13 -8 -29 -10zM986 1438
+h-388l190 -200l554 200h-280q-16 -16 -38 -16t-38 16zM1689 226q1 6 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427l333 -343q8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6q14 -5 22 -13zM552 226h402l64 66
+l-309 321l-157 -166v-221zM359 226h163v189l-168 -177q4 -8 5 -12zM358 1051q0 -1 0.5 -2t0.5 -2q0 -16 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314l-223 236zM556 1425l-4 -8v-264l205 74l-191 201q-6 -2 -10 -3zM1447 1438h-16l-621 -224l213 -225zM1023 946
+l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018q-8 13 -8 29v2l-216 376q-5 1 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196l-48 -227l130 227h-82
+zM1729 266l207 361q-2 10 -2 14q0 1 3 16l-171 296l-129 -612l77 -82q5 3 15 7z" />
+    <glyph glyph-name="f210" unicode="&#xf210;" 
+d="M0 856q0 131 91.5 226.5t222.5 95.5h742l352 358v-1470q0 -132 -91.5 -227t-222.5 -95h-780q-131 0 -222.5 95t-91.5 227v790zM1232 102l-176 180v425q0 46 -32 79t-78 33h-484q-46 0 -78 -33t-32 -79v-492q0 -46 32.5 -79.5t77.5 -33.5h770z" />
+    <glyph glyph-name="_496" unicode="&#xf211;" 
+d="M934 1386q-317 -121 -556 -362.5t-358 -560.5q-20 89 -20 176q0 208 102.5 384.5t278.5 279t384 102.5q82 0 169 -19zM1203 1267q93 -65 164 -155q-389 -113 -674.5 -400.5t-396.5 -676.5q-93 72 -155 162q112 386 395 671t667 399zM470 -67q115 356 379.5 622t619.5 384
+q40 -92 54 -195q-292 -120 -516 -345t-343 -518q-103 14 -194 52zM1536 -125q-193 50 -367 115q-135 -84 -290 -107q109 205 274 370.5t369 275.5q-21 -152 -101 -284q65 -175 115 -370z" />
+    <glyph glyph-name="f212" unicode="&#xf212;" horiz-adv-x="2048" 
+d="M1893 1144l155 -1272q-131 0 -257 57q-200 91 -393 91q-226 0 -374 -148q-148 148 -374 148q-193 0 -393 -91q-128 -57 -252 -57h-5l155 1272q224 127 482 127q233 0 387 -106q154 106 387 106q258 0 482 -127zM1398 157q129 0 232 -28.5t260 -93.5l-124 1021
+q-171 78 -368 78q-224 0 -374 -141q-150 141 -374 141q-197 0 -368 -78l-124 -1021q105 43 165.5 65t148.5 39.5t178 17.5q202 0 374 -108q172 108 374 108zM1438 191l-55 907q-211 -4 -359 -155q-152 155 -374 155q-176 0 -336 -66l-114 -941q124 51 228.5 76t221.5 25
+q209 0 374 -102q172 107 374 102z" />
+    <glyph glyph-name="_498" unicode="&#xf213;" horiz-adv-x="2048" 
+d="M1500 165v733q0 21 -15 36t-35 15h-93q-20 0 -35 -15t-15 -36v-733q0 -20 15 -35t35 -15h93q20 0 35 15t15 35zM1216 165v531q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-531q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM924 165v429q0 20 -15 35t-35 15h-101
+q-20 0 -35 -15t-15 -35v-429q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM632 165v362q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-362q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM2048 311q0 -166 -118 -284t-284 -118h-1244q-166 0 -284 118t-118 284
+q0 116 63 214.5t168 148.5q-10 34 -10 73q0 113 80.5 193.5t193.5 80.5q102 0 180 -67q45 183 194 300t338 117q149 0 275 -73.5t199.5 -199.5t73.5 -275q0 -66 -14 -122q135 -33 221 -142.5t86 -247.5z" />
+    <glyph glyph-name="_499" unicode="&#xf214;" 
+d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34
+l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114
+v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z
+M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378
+v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265q-129 0 -221 91.5t-92 221.5q0 129 92 221t221 92q130 0 221.5 -92t91.5 -221q0 -130 -91.5 -221.5t-221.5 -91.5zM595 646q0 -36 19.5 -56.5t49.5 -25t64 -7t64 -2t49.5 -9t19.5 -30.5q0 -49 -112 -49q-97 0 -123 51
+h-3l-31 -63q67 -42 162 -42q29 0 56.5 5t55.5 16t45.5 33t17.5 53q0 46 -27.5 69.5t-67.5 27t-79.5 3t-67 5t-27.5 25.5q0 21 20.5 33t40.5 15t41 3q34 0 70.5 -11t51.5 -34h3l30 58q-3 1 -21 8.5t-22.5 9t-19.5 7t-22 7t-20 4.5t-24 4t-23 1q-29 0 -56.5 -5t-54 -16.5
+t-43 -34t-16.5 -53.5z" />
+    <glyph glyph-name="_500" unicode="&#xf215;" horiz-adv-x="2048" 
+d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832
+q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" />
+    <glyph glyph-name="_501" unicode="&#xf216;" horiz-adv-x="2048" 
+d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126t-103.5 132.5t-108.5 126.5t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5
+t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113
+t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5
+q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" />
+    <glyph glyph-name="_502" unicode="&#xf217;" horiz-adv-x="1664" 
+d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
+t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920
+q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="_503" unicode="&#xf218;" horiz-adv-x="1664" 
+d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
+t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920
+q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="_504" unicode="&#xf219;" horiz-adv-x="2048" 
+d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20
+l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" />
+    <glyph glyph-name="_505" unicode="&#xf21a;" horiz-adv-x="2048" 
+d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83
+q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83
+q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314
+v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83
+q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" />
+    <glyph glyph-name="_506" unicode="&#xf21b;" 
+d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14
+t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5
+q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31
+t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" />
+    <glyph glyph-name="_507" unicode="&#xf21c;" horiz-adv-x="2304" 
+d="M2301 500q12 -103 -22 -198.5t-99 -163.5t-158.5 -106t-196.5 -31q-161 11 -279.5 125t-134.5 274q-12 111 27.5 210.5t118.5 170.5l-71 107q-96 -80 -151 -194t-55 -244q0 -27 -18.5 -46.5t-45.5 -19.5h-256h-69q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5
+t-131.5 316.5t131.5 316.5t316.5 131.5q76 0 152 -27l24 45q-123 110 -304 110h-64q-26 0 -45 19t-19 45t19 45t45 19h128q78 0 145 -13.5t116.5 -38.5t71.5 -39.5t51 -36.5h512h115l-85 128h-222q-30 0 -49 22.5t-14 52.5q4 23 23 38t43 15h253q33 0 53 -28l70 -105
+l114 114q19 19 46 19h101q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-179l115 -172q131 63 275 36q143 -26 244 -134.5t118 -253.5zM448 128q115 0 203 72.5t111 183.5h-314q-35 0 -55 31q-18 32 -1 63l147 277q-47 13 -91 13q-132 0 -226 -94t-94 -226t94 -226
+t226 -94zM1856 128q132 0 226 94t94 226t-94 226t-226 94q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94z" />
+    <glyph glyph-name="_508" unicode="&#xf21d;" 
+d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12
+q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384
+q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5
+t158.5 -65.5t65.5 -158.5z" />
+    <glyph glyph-name="_509" unicode="&#xf21e;" horiz-adv-x="1792" 
+d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221
+q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124
+t127 -344z" />
+    <glyph glyph-name="venus" unicode="&#xf221;" horiz-adv-x="1280" 
+d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292
+q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" />
+    <glyph glyph-name="_511" unicode="&#xf222;" 
+d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-382 -383q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5
+q203 0 359 -126l382 382h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+    <glyph glyph-name="_512" unicode="&#xf223;" horiz-adv-x="1280" 
+d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5
+t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
+t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+    <glyph glyph-name="_513" unicode="&#xf224;" 
+d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64
+q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
+t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+    <glyph glyph-name="_514" unicode="&#xf225;" horiz-adv-x="1792" 
+d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64
+q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9
+t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5
+t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+    <glyph glyph-name="_515" unicode="&#xf226;" horiz-adv-x="1792" 
+d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23
+t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391
+q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391
+q0 -226 -154 -391q103 -57 218 -57z" />
+    <glyph glyph-name="_516" unicode="&#xf227;" horiz-adv-x="1920" 
+d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230
+q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9
+t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128
+q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -28 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" />
+    <glyph glyph-name="_517" unicode="&#xf228;" horiz-adv-x="2048" 
+d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23
+t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9
+t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5
+t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" />
+    <glyph glyph-name="_518" unicode="&#xf229;" 
+d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-213 -214l140 -140q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-140 141l-78 -79q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5
+t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5q203 0 359 -126l78 78l-172 172q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l172 -172l213 213h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
+t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+    <glyph glyph-name="_519" unicode="&#xf22a;" horiz-adv-x="1280" 
+d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22
+t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5
+t131.5 -316.5t316.5 -131.5z" />
+    <glyph glyph-name="_520" unicode="&#xf22b;" horiz-adv-x="2048" 
+d="M1901 621q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-132q-24 -217 -187.5 -364.5t-384.5 -147.5q-167 0 -306 87t-212 236t-54 319q15 133 88 245.5
+t188 182t249 80.5q155 12 292 -52.5t224 -186t103 -271.5h132v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM576 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5
+t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+    <glyph glyph-name="_521" unicode="&#xf22c;" horiz-adv-x="1280" 
+d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5
+t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+    <glyph glyph-name="_522" unicode="&#xf22d;" horiz-adv-x="1280" 
+d="M1024 576q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1152 576q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123
+t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5z" />
+    <glyph glyph-name="_523" unicode="&#xf22e;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="_524" unicode="&#xf22f;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="_525" unicode="&#xf230;" 
+d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" />
+    <glyph glyph-name="_526" unicode="&#xf231;" horiz-adv-x="1280" 
+d="M0 939q0 108 37.5 203.5t103.5 166.5t152 123t185 78t202 26q158 0 294 -66.5t221 -193.5t85 -287q0 -96 -19 -188t-60 -177t-100 -149.5t-145 -103t-189 -38.5q-68 0 -135 32t-96 88q-10 -39 -28 -112.5t-23.5 -95t-20.5 -71t-26 -71t-32 -62.5t-46 -77.5t-62 -86.5
+l-14 -5l-9 10q-15 157 -15 188q0 92 21.5 206.5t66.5 287.5t52 203q-32 65 -32 169q0 83 52 156t132 73q61 0 95 -40.5t34 -102.5q0 -66 -44 -191t-44 -187q0 -63 45 -104.5t109 -41.5q55 0 102 25t78.5 68t56 95t38 110.5t20 111t6.5 99.5q0 173 -109.5 269.5t-285.5 96.5
+q-200 0 -334 -129.5t-134 -328.5q0 -44 12.5 -85t27 -65t27 -45.5t12.5 -30.5q0 -28 -15 -73t-37 -45q-2 0 -17 3q-51 15 -90.5 56t-61 94.5t-32.5 108t-11 106.5z" />
+    <glyph glyph-name="_527" unicode="&#xf232;" 
+d="M985 562q13 0 97.5 -44t89.5 -53q2 -5 2 -15q0 -33 -17 -76q-16 -39 -71 -65.5t-102 -26.5q-57 0 -190 62q-98 45 -170 118t-148 185q-72 107 -71 194v8q3 91 74 158q24 22 52 22q6 0 18 -1.5t19 -1.5q19 0 26.5 -6.5t15.5 -27.5q8 -20 33 -88t25 -75q0 -21 -34.5 -57.5
+t-34.5 -46.5q0 -7 5 -15q34 -73 102 -137q56 -53 151 -101q12 -7 22 -7q15 0 54 48.5t52 48.5zM782 32q127 0 243.5 50t200.5 134t134 200.5t50 243.5t-50 243.5t-134 200.5t-200.5 134t-243.5 50t-243.5 -50t-200.5 -134t-134 -200.5t-50 -243.5q0 -203 120 -368l-79 -233
+l242 77q158 -104 345 -104zM782 1414q153 0 292.5 -60t240.5 -161t161 -240.5t60 -292.5t-60 -292.5t-161 -240.5t-240.5 -161t-292.5 -60q-195 0 -365 94l-417 -134l136 405q-108 178 -108 389q0 153 60 292.5t161 240.5t240.5 161t292.5 60z" />
+    <glyph glyph-name="_528" unicode="&#xf233;" horiz-adv-x="1792" 
+d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM128 1152h1024v128h-1024v-128zM1696 704q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1696 1216
+q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" />
+    <glyph glyph-name="_529" unicode="&#xf234;" horiz-adv-x="2048" 
+d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1664 512h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-352q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5
+t-9.5 22.5v352h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v352q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-352zM928 288q0 -52 38 -90t90 -38h256v-238q-68 -50 -171 -50h-874q-121 0 -194 69t-73 190q0 53 3.5 103.5t14 109t26.5 108.5
+t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q79 -61 154.5 -91.5t164.5 -30.5t164.5 30.5t154.5 91.5q20 17 39 17q132 0 217 -96h-223q-52 0 -90 -38t-38 -90v-192z" />
+    <glyph glyph-name="_530" unicode="&#xf235;" horiz-adv-x="2048" 
+d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1781 320l249 -249q9 -9 9 -23q0 -13 -9 -22l-136 -136q-9 -9 -22 -9q-14 0 -23 9l-249 249l-249 -249q-9 -9 -23 -9q-13 0 -22 9l-136 136
+q-9 9 -9 22q0 14 9 23l249 249l-249 249q-9 9 -9 23q0 13 9 22l136 136q9 9 22 9q14 0 23 -9l249 -249l249 249q9 9 23 9q13 0 22 -9l136 -136q9 -9 9 -22q0 -14 -9 -23zM1283 320l-181 -181q-37 -37 -37 -91q0 -53 37 -90l83 -83q-21 -3 -44 -3h-874q-121 0 -194 69
+t-73 190q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q154 -122 319 -122t319 122q20 17 39 17q28 0 57 -6q-28 -27 -41 -50t-13 -56q0 -54 37 -91z" />
+    <glyph glyph-name="_531" unicode="&#xf236;" horiz-adv-x="2048" 
+d="M256 512h1728q26 0 45 -19t19 -45v-448h-256v256h-1536v-256h-256v1216q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-704zM832 832q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM2048 576v64q0 159 -112.5 271.5t-271.5 112.5h-704
+q-26 0 -45 -19t-19 -45v-384h1152z" />
+    <glyph glyph-name="_532" unicode="&#xf237;" 
+d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" />
+    <glyph glyph-name="_533" unicode="&#xf238;" 
+d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56
+t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" />
+    <glyph glyph-name="_534" unicode="&#xf239;" 
+d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47
+t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" />
+    <glyph glyph-name="_535" unicode="&#xf23a;" horiz-adv-x="1792" 
+d="M597 1115v-1173q0 -25 -12.5 -42.5t-36.5 -17.5q-17 0 -33 8l-465 233q-21 10 -35.5 33.5t-14.5 46.5v1140q0 20 10 34t29 14q14 0 44 -15l511 -256q3 -3 3 -5zM661 1014l534 -866l-534 266v600zM1792 996v-1054q0 -25 -14 -40.5t-38 -15.5t-47 13l-441 220zM1789 1116
+q0 -3 -256.5 -419.5t-300.5 -487.5l-390 634l324 527q17 28 52 28q14 0 26 -6l541 -270q4 -2 4 -6z" />
+    <glyph glyph-name="_536" unicode="&#xf23b;" 
+d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1408v-1536h-1536v1536h1536z" />
+    <glyph glyph-name="_537" unicode="&#xf23c;" horiz-adv-x="2296" 
+d="M478 -139q-8 -16 -27 -34.5t-37 -25.5q-25 -9 -51.5 3.5t-28.5 31.5q-1 22 40 55t68 38q23 4 34 -21.5t2 -46.5zM1819 -139q7 -16 26 -34.5t38 -25.5q25 -9 51.5 3.5t27.5 31.5q2 22 -39.5 55t-68.5 38q-22 4 -33 -21.5t-2 -46.5zM1867 -30q13 -27 56.5 -59.5t77.5 -41.5
+q45 -13 82 4.5t37 50.5q0 46 -67.5 100.5t-115.5 59.5q-40 5 -63.5 -37.5t-6.5 -76.5zM428 -30q-13 -27 -56 -59.5t-77 -41.5q-45 -13 -82 4.5t-37 50.5q0 46 67.5 100.5t115.5 59.5q40 5 63 -37.5t6 -76.5zM1158 1094h1q-41 0 -76 -15q27 -8 44 -30.5t17 -49.5
+q0 -35 -27 -60t-65 -25q-52 0 -80 43q-5 -23 -5 -42q0 -74 56 -126.5t135 -52.5q80 0 136 52.5t56 126.5t-56 126.5t-136 52.5zM1462 1312q-99 109 -220.5 131.5t-245.5 -44.5q27 60 82.5 96.5t118 39.5t121.5 -17t99.5 -74.5t44.5 -131.5zM2212 73q8 -11 -11 -42
+q7 -23 7 -40q1 -56 -44.5 -112.5t-109.5 -91.5t-118 -37q-48 -2 -92 21.5t-66 65.5q-687 -25 -1259 0q-23 -41 -66.5 -65t-92.5 -22q-86 3 -179.5 80.5t-92.5 160.5q2 22 7 40q-19 31 -11 42q6 10 31 1q14 22 41 51q-7 29 2 38q11 10 39 -4q29 20 59 34q0 29 13 37
+q23 12 51 -16q35 5 61 -2q18 -4 38 -19v73q-11 0 -18 2q-53 10 -97 44.5t-55 87.5q-9 38 0 81q15 62 93 95q2 17 19 35.5t36 23.5t33 -7.5t19 -30.5h13q46 -5 60 -23q3 -3 5 -7q10 1 30.5 3.5t30.5 3.5q-15 11 -30 17q-23 40 -91 43q0 6 1 10q-62 2 -118.5 18.5t-84.5 47.5
+q-32 36 -42.5 92t-2.5 112q16 126 90 179q23 16 52 4.5t32 -40.5q0 -1 1.5 -14t2.5 -21t3 -20t5.5 -19t8.5 -10q27 -14 76 -12q48 46 98 74q-40 4 -162 -14l47 46q61 58 163 111q145 73 282 86q-20 8 -41 15.5t-47 14t-42.5 10.5t-47.5 11t-43 10q595 126 904 -139
+q98 -84 158 -222q85 -10 121 9h1q5 3 8.5 10t5.5 19t3 19.5t3 21.5l1 14q3 28 32 40t52 -5q73 -52 91 -178q7 -57 -3.5 -113t-42.5 -91q-28 -32 -83.5 -48.5t-115.5 -18.5v-10q-71 -2 -95 -43q-14 -5 -31 -17q11 -1 32 -3.5t30 -3.5q1 5 5 8q16 18 60 23h13q5 18 19 30t33 8
+t36 -23t19 -36q79 -32 93 -95q9 -40 1 -81q-12 -53 -56 -88t-97 -44q-10 -2 -17 -2q0 -49 -1 -73q20 15 38 19q26 7 61 2q28 28 51 16q14 -9 14 -37q33 -16 59 -34q27 13 38 4q10 -10 2 -38q28 -30 41 -51q23 8 31 -1zM1937 1025q0 -29 -9 -54q82 -32 112 -132
+q4 37 -9.5 98.5t-41.5 90.5q-20 19 -36 17t-16 -20zM1859 925q35 -42 47.5 -108.5t-0.5 -124.5q67 13 97 45q13 14 18 28q-3 64 -31 114.5t-79 66.5q-15 -15 -52 -21zM1822 921q-30 0 -44 1q42 -115 53 -239q21 0 43 3q16 68 1 135t-53 100zM258 839q30 100 112 132
+q-9 25 -9 54q0 18 -16.5 20t-35.5 -17q-28 -29 -41.5 -90.5t-9.5 -98.5zM294 737q29 -31 97 -45q-13 58 -0.5 124.5t47.5 108.5v0q-37 6 -52 21q-51 -16 -78.5 -66t-31.5 -115q9 -17 18 -28zM471 683q14 124 73 235q-19 -4 -55 -18l-45 -19v1q-46 -89 -20 -196q25 -3 47 -3z
+M1434 644q8 -38 16.5 -108.5t11.5 -89.5q3 -18 9.5 -21.5t23.5 4.5q40 20 62 85.5t23 125.5q-24 2 -146 4zM1152 1285q-116 0 -199 -82.5t-83 -198.5q0 -117 83 -199.5t199 -82.5t199 82.5t83 199.5q0 116 -83 198.5t-199 82.5zM1380 646q-105 2 -211 0v1q-1 -27 2.5 -86
+t13.5 -66q29 -14 93.5 -14.5t95.5 10.5q9 3 11 39t-0.5 69.5t-4.5 46.5zM1112 447q8 4 9.5 48t-0.5 88t-4 63v1q-212 -3 -214 -3q-4 -20 -7 -62t0 -83t14 -46q34 -15 101 -16t101 10zM718 636q-16 -59 4.5 -118.5t77.5 -84.5q15 -8 24 -5t12 21q3 16 8 90t10 103
+q-69 -2 -136 -6zM591 510q3 -23 -34 -36q132 -141 271.5 -240t305.5 -154q172 49 310.5 146t293.5 250q-33 13 -30 34q0 2 0.5 3.5t1.5 3t1 2.5v1v-1q-17 2 -50 5.5t-48 4.5q-26 -90 -82 -132q-51 -38 -82 1q-5 6 -9 14q-7 13 -17 62q-2 -5 -5 -9t-7.5 -7t-8 -5.5t-9.5 -4
+l-10 -2.5t-12 -2l-12 -1.5t-13.5 -1t-13.5 -0.5q-106 -9 -163 11q-4 -17 -10 -26.5t-21 -15t-23 -7t-36 -3.5q-6 -1 -9 -1q-179 -17 -203 40q-2 -63 -56 -54q-47 8 -91 54q-12 13 -20 26q-17 29 -26 65q-58 -6 -87 -10q1 -2 4 -10zM507 -118q3 14 3 30q-17 71 -51 130
+t-73 70q-41 12 -101.5 -14.5t-104.5 -80t-39 -107.5q35 -53 100 -93t119 -42q51 -2 94 28t53 79zM510 53q23 -63 27 -119q195 113 392 174q-98 52 -180.5 120t-179.5 165q-6 -4 -29 -13q0 -1 -1 -4t-1 -5q31 -18 22 -37q-12 -23 -56 -34q-10 -13 -29 -24h-1q-2 -83 1 -150
+q19 -34 35 -73zM579 -113q532 -21 1145 0q-254 147 -428 196q-76 -35 -156 -57q-8 -3 -16 0q-65 21 -129 49q-208 -60 -416 -188h-1v-1q1 0 1 1zM1763 -67q4 54 28 120q14 38 33 71l-1 -1q3 77 3 153q-15 8 -30 25q-42 9 -56 33q-9 20 22 38q-2 4 -2 9q-16 4 -28 12
+q-204 -190 -383 -284q198 -59 414 -176zM2155 -90q5 54 -39 107.5t-104 80t-102 14.5q-38 -11 -72.5 -70.5t-51.5 -129.5q0 -16 3 -30q10 -49 53 -79t94 -28q54 2 119 42t100 93z" />
+    <glyph glyph-name="_538" unicode="&#xf23d;" horiz-adv-x="2304" 
+d="M1524 -25q0 -68 -48 -116t-116 -48t-116.5 48t-48.5 116t48.5 116.5t116.5 48.5t116 -48.5t48 -116.5zM775 -25q0 -68 -48.5 -116t-116.5 -48t-116 48t-48 116t48 116.5t116 48.5t116.5 -48.5t48.5 -116.5zM0 1469q57 -60 110.5 -104.5t121 -82t136 -63t166 -45.5
+t200 -31.5t250 -18.5t304 -9.5t372.5 -2.5q139 0 244.5 -5t181 -16.5t124 -27.5t71 -39.5t24 -51.5t-19.5 -64t-56.5 -76.5t-89.5 -91t-116 -104.5t-139 -119q-185 -157 -286 -247q29 51 76.5 109t94 105.5t94.5 98.5t83 91.5t54 80.5t13 70t-45.5 55.5t-116.5 41t-204 23.5
+t-304 5q-168 -2 -314 6t-256 23t-204.5 41t-159.5 51.5t-122.5 62.5t-91.5 66.5t-68 71.5t-50.5 69.5t-40 68t-36.5 59.5z" />
+    <glyph glyph-name="_539" unicode="&#xf23e;" horiz-adv-x="1792" 
+d="M896 1472q-169 0 -323 -66t-265.5 -177.5t-177.5 -265.5t-66 -323t66 -323t177.5 -265.5t265.5 -177.5t323 -66t323 66t265.5 177.5t177.5 265.5t66 323t-66 323t-177.5 265.5t-265.5 177.5t-323 66zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348
+t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM496 704q16 0 16 -16v-480q0 -16 -16 -16h-32q-16 0 -16 16v480q0 16 16 16h32zM896 640q53 0 90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-114q0 -14 -9 -23
+t-23 -9h-64q-14 0 -23 9t-9 23v114q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5zM896 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM544 928v-96
+q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5v-96q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 146 -103 249t-249 103t-249 -103t-103 -249zM1408 192v512q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-512
+q0 -26 19 -45t45 -19h896q26 0 45 19t19 45z" />
+    <glyph glyph-name="_540" unicode="&#xf240;" horiz-adv-x="2304" 
+d="M1920 1024v-768h-1664v768h1664zM2048 448h128v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288zM2304 832v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113
+v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160q53 0 90.5 -37.5t37.5 -90.5z" />
+    <glyph glyph-name="_541" unicode="&#xf241;" horiz-adv-x="2304" 
+d="M256 256v768h1280v-768h-1280zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
+h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
+    <glyph glyph-name="_542" unicode="&#xf242;" horiz-adv-x="2304" 
+d="M256 256v768h896v-768h-896zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
+h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
+    <glyph glyph-name="_543" unicode="&#xf243;" horiz-adv-x="2304" 
+d="M256 256v768h512v-768h-512zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
+h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
+    <glyph glyph-name="_544" unicode="&#xf244;" horiz-adv-x="2304" 
+d="M2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23
+v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
+    <glyph glyph-name="_545" unicode="&#xf245;" horiz-adv-x="1280" 
+d="M1133 493q31 -30 14 -69q-17 -40 -59 -40h-382l201 -476q10 -25 0 -49t-34 -35l-177 -75q-25 -10 -49 0t-35 34l-191 452l-312 -312q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v1504q0 42 40 59q12 5 24 5q27 0 45 -19z" />
+    <glyph glyph-name="_546" unicode="&#xf246;" horiz-adv-x="1024" 
+d="M832 1408q-320 0 -320 -224v-416h128v-128h-128v-544q0 -224 320 -224h64v-128h-64q-272 0 -384 146q-112 -146 -384 -146h-64v128h64q320 0 320 224v544h-128v128h128v416q0 224 -320 224h-64v128h64q272 0 384 -146q112 146 384 146h64v-128h-64z" />
+    <glyph glyph-name="_547" unicode="&#xf247;" horiz-adv-x="2048" 
+d="M2048 1152h-128v-1024h128v-384h-384v128h-1280v-128h-384v384h128v1024h-128v384h384v-128h1280v128h384v-384zM1792 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 -128v128h-128v-128h128zM1664 0v128h128v1024h-128v128h-1280v-128h-128v-1024h128v-128
+h1280zM1920 -128v128h-128v-128h128zM1280 896h384v-768h-896v256h-384v768h896v-256zM512 512h640v512h-640v-512zM1536 256v512h-256v-384h-384v-128h640z" />
+    <glyph glyph-name="_548" unicode="&#xf248;" horiz-adv-x="2304" 
+d="M2304 768h-128v-640h128v-384h-384v128h-896v-128h-384v384h128v128h-384v-128h-384v384h128v640h-128v384h384v-128h896v128h384v-384h-128v-128h384v128h384v-384zM2048 1024v-128h128v128h-128zM1408 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 256
+v128h-128v-128h128zM1536 384h-128v-128h128v128zM384 384h896v128h128v640h-128v128h-896v-128h-128v-640h128v-128zM896 -128v128h-128v-128h128zM2176 -128v128h-128v-128h128zM2048 128v640h-128v128h-384v-384h128v-384h-384v128h-384v-128h128v-128h896v128h128z" />
+    <glyph glyph-name="_549" unicode="&#xf249;" 
+d="M1024 288v-416h-928q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68v-928h-416q-40 0 -68 -28t-28 -68zM1152 256h381q-15 -82 -65 -132l-184 -184q-50 -50 -132 -65v381z" />
+    <glyph glyph-name="_550" unicode="&#xf24a;" 
+d="M1400 256h-248v-248q29 10 41 22l185 185q12 12 22 41zM1120 384h288v896h-1280v-1280h896v288q0 40 28 68t68 28zM1536 1312v-1024q0 -40 -20 -88t-48 -76l-184 -184q-28 -28 -76 -48t-88 -20h-1024q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68
+z" />
+    <glyph glyph-name="_551" unicode="&#xf24b;" horiz-adv-x="2304" 
+d="M1951 538q0 -26 -15.5 -44.5t-38.5 -23.5q-8 -2 -18 -2h-153v140h153q10 0 18 -2q23 -5 38.5 -23.5t15.5 -44.5zM1933 751q0 -25 -15 -42t-38 -21q-3 -1 -15 -1h-139v129h139q3 0 8.5 -0.5t6.5 -0.5q23 -4 38 -21.5t15 -42.5zM728 587v308h-228v-308q0 -58 -38 -94.5
+t-105 -36.5q-108 0 -229 59v-112q53 -15 121 -23t109 -9l42 -1q328 0 328 217zM1442 403v113q-99 -52 -200 -59q-108 -8 -169 41t-61 142t61 142t169 41q101 -7 200 -58v112q-48 12 -100 19.5t-80 9.5l-28 2q-127 6 -218.5 -14t-140.5 -60t-71 -88t-22 -106t22 -106t71 -88
+t140.5 -60t218.5 -14q101 4 208 31zM2176 518q0 54 -43 88.5t-109 39.5v3q57 8 89 41.5t32 79.5q0 55 -41 88t-107 36q-3 0 -12 0.5t-14 0.5h-455v-510h491q74 0 121.5 36.5t47.5 96.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90
+t90 38h2048q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="_552" unicode="&#xf24c;" horiz-adv-x="2304" 
+d="M858 295v693q-106 -41 -172 -135.5t-66 -211.5t66 -211.5t172 -134.5zM1362 641q0 117 -66 211.5t-172 135.5v-694q106 41 172 135.5t66 211.5zM1577 641q0 -159 -78.5 -294t-213.5 -213.5t-294 -78.5q-119 0 -227.5 46.5t-187 125t-125 187t-46.5 227.5q0 159 78.5 294
+t213.5 213.5t294 78.5t294 -78.5t213.5 -213.5t78.5 -294zM1960 634q0 139 -55.5 261.5t-147.5 205.5t-213.5 131t-252.5 48h-301q-176 0 -323.5 -81t-235 -230t-87.5 -335q0 -171 87 -317.5t236 -231.5t323 -85h301q129 0 251.5 50.5t214.5 135t147.5 202.5t55.5 246z
+M2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="_553" unicode="&#xf24d;" horiz-adv-x="1792" 
+d="M1664 -96v1088q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5zM1792 992v-1088q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113
+zM1408 1376v-160h-128v160q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h160v-128h-160q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="_554" unicode="&#xf24e;" horiz-adv-x="2304" 
+d="M1728 1088l-384 -704h768zM448 1088l-384 -704h768zM1269 1280q-14 -40 -45.5 -71.5t-71.5 -45.5v-1291h608q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1344q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h608v1291q-40 14 -71.5 45.5t-45.5 71.5h-491q-14 0 -23 9t-9 23v64
+q0 14 9 23t23 9h491q21 57 70 92.5t111 35.5t111 -35.5t70 -92.5h491q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-491zM1088 1264q33 0 56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5zM2176 384q0 -73 -46.5 -131t-117.5 -91
+t-144.5 -49.5t-139.5 -16.5t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81zM896 384q0 -73 -46.5 -131t-117.5 -91t-144.5 -49.5t-139.5 -16.5
+t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81z" />
+    <glyph glyph-name="_555" unicode="&#xf250;" 
+d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
+t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-77 -29 -149 -92.5
+t-129.5 -152.5t-92.5 -210t-35 -253h1024q0 132 -35 253t-92.5 210t-129.5 152.5t-149 92.5q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" />
+    <glyph glyph-name="_556" unicode="&#xf251;" 
+d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
+t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -66 9 -128h1006q9 61 9 128zM1280 -128q0 130 -34 249.5t-90.5 208t-126.5 152t-146 94.5h-230q-76 -31 -146 -94.5t-126.5 -152t-90.5 -208t-34 -249.5h1024z" />
+    <glyph glyph-name="_557" unicode="&#xf252;" 
+d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
+t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -206 85 -384h854q85 178 85 384zM1223 192q-54 141 -145.5 241.5t-194.5 142.5h-230q-103 -42 -194.5 -142.5t-145.5 -241.5h910z" />
+    <glyph glyph-name="_558" unicode="&#xf253;" 
+d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
+t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-137 -51 -244 -196
+h700q-107 145 -244 196q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" />
+    <glyph glyph-name="_559" unicode="&#xf254;" 
+d="M1504 -64q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472zM130 0q3 55 16 107t30 95t46 87t53.5 76t64.5 69.5t66 60t70.5 55t66.5 47.5t65 43q-43 28 -65 43t-66.5 47.5t-70.5 55t-66 60t-64.5 69.5t-53.5 76t-46 87
+t-30 95t-16 107h1276q-3 -55 -16 -107t-30 -95t-46 -87t-53.5 -76t-64.5 -69.5t-66 -60t-70.5 -55t-66.5 -47.5t-65 -43q43 -28 65 -43t66.5 -47.5t70.5 -55t66 -60t64.5 -69.5t53.5 -76t46 -87t30 -95t16 -107h-1276zM1504 1536q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9
+h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472z" />
+    <glyph glyph-name="_560" unicode="&#xf255;" 
+d="M768 1152q-53 0 -90.5 -37.5t-37.5 -90.5v-128h-32v93q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-429l-32 30v172q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-224q0 -47 35 -82l310 -296q39 -39 39 -102q0 -26 19 -45t45 -19h640q26 0 45 19t19 45v25
+q0 41 10 77l108 436q10 36 10 77v246q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-32h-32v125q0 40 -25 72.5t-64 40.5q-14 2 -23 2q-46 0 -79 -33t-33 -79v-128h-32v122q0 51 -32.5 89.5t-82.5 43.5q-5 1 -13 1zM768 1280q84 0 149 -50q57 34 123 34q59 0 111 -27
+t86 -76q27 7 59 7q100 0 170 -71.5t70 -171.5v-246q0 -51 -13 -108l-109 -436q-6 -24 -6 -71q0 -80 -56 -136t-136 -56h-640q-84 0 -138 58.5t-54 142.5l-308 296q-76 73 -76 175v224q0 99 70.5 169.5t169.5 70.5q11 0 16 -1q6 95 75.5 160t164.5 65q52 0 98 -21
+q72 69 174 69z" />
+    <glyph glyph-name="_561" unicode="&#xf256;" horiz-adv-x="1792" 
+d="M880 1408q-46 0 -79 -33t-33 -79v-656h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528v-256l-154 205q-38 51 -102 51q-53 0 -90.5 -37.5t-37.5 -90.5q0 -43 26 -77l384 -512q38 -51 102 -51h688q34 0 61 22t34 56l76 405q5 32 5 59v498q0 46 -33 79t-79 33t-79 -33
+t-33 -79v-272h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528h-32v656q0 46 -33 79t-79 33zM880 1536q68 0 125.5 -35.5t88.5 -96.5q19 4 42 4q99 0 169.5 -70.5t70.5 -169.5v-17q105 6 180.5 -64t75.5 -175v-498q0 -40 -8 -83l-76 -404q-14 -79 -76.5 -131t-143.5 -52
+h-688q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 106 75 181t181 75q78 0 128 -34v434q0 99 70.5 169.5t169.5 70.5q23 0 42 -4q31 61 88.5 96.5t125.5 35.5z" />
+    <glyph glyph-name="_562" unicode="&#xf257;" horiz-adv-x="1792" 
+d="M1073 -128h-177q-163 0 -226 141q-23 49 -23 102v5q-62 30 -98.5 88.5t-36.5 127.5q0 38 5 48h-261q-106 0 -181 75t-75 181t75 181t181 75h113l-44 17q-74 28 -119.5 93.5t-45.5 145.5q0 106 75 181t181 75q46 0 91 -17l628 -239h401q106 0 181 -75t75 -181v-668
+q0 -88 -54 -157.5t-140 -90.5l-339 -85q-92 -23 -186 -23zM1024 583l-155 -71l-163 -74q-30 -14 -48 -41.5t-18 -60.5q0 -46 33 -79t79 -33q26 0 46 10l338 154q-49 10 -80.5 50t-31.5 90v55zM1344 272q0 46 -33 79t-79 33q-26 0 -46 -10l-290 -132q-28 -13 -37 -17
+t-30.5 -17t-29.5 -23.5t-16 -29t-8 -40.5q0 -50 31.5 -82t81.5 -32q20 0 38 9l352 160q30 14 48 41.5t18 60.5zM1112 1024l-650 248q-24 8 -46 8q-53 0 -90.5 -37.5t-37.5 -90.5q0 -40 22.5 -73t59.5 -47l526 -200v-64h-640q-53 0 -90.5 -37.5t-37.5 -90.5t37.5 -90.5
+t90.5 -37.5h535l233 106v198q0 63 46 106l111 102h-69zM1073 0q82 0 155 19l339 85q43 11 70 45.5t27 78.5v668q0 53 -37.5 90.5t-90.5 37.5h-308l-136 -126q-36 -33 -36 -82v-296q0 -46 33 -77t79 -31t79 35t33 81v208h32v-208q0 -70 -57 -114q52 -8 86.5 -48.5t34.5 -93.5
+q0 -42 -23 -78t-61 -53l-310 -141h91z" />
+    <glyph glyph-name="_563" unicode="&#xf258;" horiz-adv-x="2048" 
+d="M1151 1536q61 0 116 -28t91 -77l572 -781q118 -159 118 -359v-355q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v177l-286 143h-546q-80 0 -136 56t-56 136v32q0 119 84.5 203.5t203.5 84.5h420l42 128h-686q-100 0 -173.5 67.5t-81.5 166.5q-65 79 -65 182v32
+q0 80 56 136t136 56h959zM1920 -64v355q0 157 -93 284l-573 781q-39 52 -103 52h-959q-26 0 -45 -19t-19 -45q0 -32 1.5 -49.5t9.5 -40.5t25 -43q10 31 35.5 50t56.5 19h832v-32h-832q-26 0 -45 -19t-19 -45q0 -44 3 -58q8 -44 44 -73t81 -29h640h91q40 0 68 -28t28 -68
+q0 -15 -5 -30l-64 -192q-10 -29 -35 -47.5t-56 -18.5h-443q-66 0 -113 -47t-47 -113v-32q0 -26 19 -45t45 -19h561q16 0 29 -7l317 -158q24 -13 38.5 -36t14.5 -50v-197q0 -26 19 -45t45 -19h384q26 0 45 19t19 45z" />
+    <glyph glyph-name="_564" unicode="&#xf259;" horiz-adv-x="2048" 
+d="M459 -256q-77 0 -137.5 47.5t-79.5 122.5l-101 401q-13 57 -13 108q0 45 -5 67l-116 477q-7 27 -7 57q0 93 62 161t155 78q17 85 82.5 139t152.5 54q83 0 148 -51.5t85 -132.5l83 -348l103 428q20 81 85 132.5t148 51.5q89 0 155.5 -57.5t80.5 -144.5q92 -10 152 -79
+t60 -162q0 -24 -7 -59l-123 -512q10 7 37.5 28.5t38.5 29.5t35 23t41 20.5t41.5 11t49.5 5.5q105 0 180 -74t75 -179q0 -62 -28.5 -118t-78.5 -94l-507 -380q-68 -51 -153 -51h-694zM1104 1408q-38 0 -68.5 -24t-39.5 -62l-164 -682h-127l-145 602q-9 38 -39.5 62t-68.5 24
+q-48 0 -80 -33t-32 -80q0 -15 3 -28l132 -547h-26l-99 408q-9 37 -40 62.5t-69 25.5q-47 0 -80 -33t-33 -79q0 -14 3 -26l116 -478q7 -28 9 -86t10 -88l100 -401q8 -32 34 -52.5t59 -20.5h694q42 0 76 26l507 379q56 43 56 110q0 52 -37.5 88.5t-89.5 36.5q-43 0 -77 -26
+l-307 -230v227q0 4 32 138t68 282t39 161q4 18 4 29q0 47 -32 81t-79 34q-39 0 -69.5 -24t-39.5 -62l-116 -482h-26l150 624q3 14 3 28q0 48 -31.5 82t-79.5 34z" />
+    <glyph glyph-name="_565" unicode="&#xf25a;" horiz-adv-x="1792" 
+d="M640 1408q-53 0 -90.5 -37.5t-37.5 -90.5v-512v-384l-151 202q-41 54 -107 54q-52 0 -89 -38t-37 -90q0 -43 26 -77l384 -512q38 -51 102 -51h718q22 0 39.5 13.5t22.5 34.5l92 368q24 96 24 194v217q0 41 -28 71t-68 30t-68 -28t-28 -68h-32v61q0 48 -32 81.5t-80 33.5
+q-46 0 -79 -33t-33 -79v-64h-32v90q0 55 -37 94.5t-91 39.5q-53 0 -90.5 -37.5t-37.5 -90.5v-96h-32v570q0 55 -37 94.5t-91 39.5zM640 1536q107 0 181.5 -77.5t74.5 -184.5v-220q22 2 32 2q99 0 173 -69q47 21 99 21q113 0 184 -87q27 7 56 7q94 0 159 -67.5t65 -161.5
+v-217q0 -116 -28 -225l-92 -368q-16 -64 -68 -104.5t-118 -40.5h-718q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 105 74.5 180.5t179.5 75.5q71 0 130 -35v547q0 106 75 181t181 75zM768 128v384h-32v-384h32zM1024 128v384h-32v-384h32zM1280 128v384h-32
+v-384h32z" />
+    <glyph glyph-name="_566" unicode="&#xf25b;" 
+d="M1288 889q60 0 107 -23q141 -63 141 -226v-177q0 -94 -23 -186l-85 -339q-21 -86 -90.5 -140t-157.5 -54h-668q-106 0 -181 75t-75 181v401l-239 628q-17 45 -17 91q0 106 75 181t181 75q80 0 145.5 -45.5t93.5 -119.5l17 -44v113q0 106 75 181t181 75t181 -75t75 -181
+v-261q27 5 48 5q69 0 127.5 -36.5t88.5 -98.5zM1072 896q-33 0 -60.5 -18t-41.5 -48l-74 -163l-71 -155h55q50 0 90 -31.5t50 -80.5l154 338q10 20 10 46q0 46 -33 79t-79 33zM1293 761q-22 0 -40.5 -8t-29 -16t-23.5 -29.5t-17 -30.5t-17 -37l-132 -290q-10 -20 -10 -46
+q0 -46 33 -79t79 -33q33 0 60.5 18t41.5 48l160 352q9 18 9 38q0 50 -32 81.5t-82 31.5zM128 1120q0 -22 8 -46l248 -650v-69l102 111q43 46 106 46h198l106 233v535q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5v-640h-64l-200 526q-14 37 -47 59.5t-73 22.5
+q-53 0 -90.5 -37.5t-37.5 -90.5zM1180 -128q44 0 78.5 27t45.5 70l85 339q19 73 19 155v91l-141 -310q-17 -38 -53 -61t-78 -23q-53 0 -93.5 34.5t-48.5 86.5q-44 -57 -114 -57h-208v32h208q46 0 81 33t35 79t-31 79t-77 33h-296q-49 0 -82 -36l-126 -136v-308
+q0 -53 37.5 -90.5t90.5 -37.5h668z" />
+    <glyph glyph-name="_567" unicode="&#xf25c;" horiz-adv-x="1973" 
+d="M857 992v-117q0 -13 -9.5 -22t-22.5 -9h-298v-812q0 -13 -9 -22.5t-22 -9.5h-135q-13 0 -22.5 9t-9.5 23v812h-297q-13 0 -22.5 9t-9.5 22v117q0 14 9 23t23 9h793q13 0 22.5 -9.5t9.5 -22.5zM1895 995l77 -961q1 -13 -8 -24q-10 -10 -23 -10h-134q-12 0 -21 8.5
+t-10 20.5l-46 588l-189 -425q-8 -19 -29 -19h-120q-20 0 -29 19l-188 427l-45 -590q-1 -12 -10 -20.5t-21 -8.5h-135q-13 0 -23 10q-9 10 -9 24l78 961q1 12 10 20.5t21 8.5h142q20 0 29 -19l220 -520q10 -24 20 -51q3 7 9.5 24.5t10.5 26.5l221 520q9 19 29 19h141
+q13 0 22 -8.5t10 -20.5z" />
+    <glyph glyph-name="_568" unicode="&#xf25d;" horiz-adv-x="1792" 
+d="M1042 833q0 88 -60 121q-33 18 -117 18h-123v-281h162q66 0 102 37t36 105zM1094 548l205 -373q8 -17 -1 -31q-8 -16 -27 -16h-152q-20 0 -28 17l-194 365h-155v-350q0 -14 -9 -23t-23 -9h-134q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h294q128 0 190 -24q85 -31 134 -109
+t49 -180q0 -92 -42.5 -165.5t-115.5 -109.5q6 -10 9 -16zM896 1376q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM1792 640
+q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="_569" unicode="&#xf25e;" horiz-adv-x="1792" 
+d="M605 303q153 0 257 104q14 18 3 36l-45 82q-6 13 -24 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78
+q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-148 0 -246 -96.5t-98 -240.5q0 -146 97 -241.5t247 -95.5zM1235 303q153 0 257 104q14 18 4 36l-45 82q-8 14 -25 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5
+t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-147 0 -245.5 -96.5t-98.5 -240.5q0 -146 97 -241.5t247 -95.5zM896 1376
+q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191
+t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71z" />
+    <glyph glyph-name="f260" unicode="&#xf260;" horiz-adv-x="2048" 
+d="M736 736l384 -384l-384 -384l-672 672l672 672l168 -168l-96 -96l-72 72l-480 -480l480 -480l193 193l-289 287zM1312 1312l672 -672l-672 -672l-168 168l96 96l72 -72l480 480l-480 480l-193 -193l289 -287l-96 -96l-384 384z" />
+    <glyph glyph-name="f261" unicode="&#xf261;" horiz-adv-x="1792" 
+d="M717 182l271 271l-279 279l-88 -88l192 -191l-96 -96l-279 279l279 279l40 -40l87 87l-127 128l-454 -454zM1075 190l454 454l-454 454l-271 -271l279 -279l88 88l-192 191l96 96l279 -279l-279 -279l-40 40l-87 -88zM1792 640q0 -182 -71 -348t-191 -286t-286 -191
+t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="_572" unicode="&#xf262;" horiz-adv-x="2304" 
+d="M651 539q0 -39 -27.5 -66.5t-65.5 -27.5q-39 0 -66.5 27.5t-27.5 66.5q0 38 27.5 65.5t66.5 27.5q38 0 65.5 -27.5t27.5 -65.5zM1805 540q0 -39 -27.5 -66.5t-66.5 -27.5t-66.5 27.5t-27.5 66.5t27.5 66t66.5 27t66.5 -27t27.5 -66zM765 539q0 79 -56.5 136t-136.5 57
+t-136.5 -56.5t-56.5 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM1918 540q0 80 -56.5 136.5t-136.5 56.5q-79 0 -136 -56.5t-57 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM850 539q0 -116 -81.5 -197.5t-196.5 -81.5q-116 0 -197.5 82t-81.5 197
+t82 196.5t197 81.5t196.5 -81.5t81.5 -196.5zM2004 540q0 -115 -81.5 -196.5t-197.5 -81.5q-115 0 -196.5 81.5t-81.5 196.5t81.5 196.5t196.5 81.5q116 0 197.5 -81.5t81.5 -196.5zM1040 537q0 191 -135.5 326.5t-326.5 135.5q-125 0 -231 -62t-168 -168.5t-62 -231.5
+t62 -231.5t168 -168.5t231 -62q191 0 326.5 135.5t135.5 326.5zM1708 1110q-254 111 -556 111q-319 0 -573 -110q117 0 223 -45.5t182.5 -122.5t122 -183t45.5 -223q0 115 43.5 219.5t118 180.5t177.5 123t217 50zM2187 537q0 191 -135 326.5t-326 135.5t-326.5 -135.5
+t-135.5 -326.5t135.5 -326.5t326.5 -135.5t326 135.5t135 326.5zM1921 1103h383q-44 -51 -75 -114.5t-40 -114.5q110 -151 110 -337q0 -156 -77 -288t-209 -208.5t-287 -76.5q-133 0 -249 56t-196 155q-47 -56 -129 -179q-11 22 -53.5 82.5t-74.5 97.5
+q-80 -99 -196.5 -155.5t-249.5 -56.5q-155 0 -287 76.5t-209 208.5t-77 288q0 186 110 337q-9 51 -40 114.5t-75 114.5h365q149 100 355 156.5t432 56.5q224 0 421 -56t348 -157z" />
+    <glyph glyph-name="f263" unicode="&#xf263;" horiz-adv-x="1280" 
+d="M640 629q-188 0 -321 133t-133 320q0 188 133 321t321 133t321 -133t133 -321q0 -187 -133 -320t-321 -133zM640 1306q-92 0 -157.5 -65.5t-65.5 -158.5q0 -92 65.5 -157.5t157.5 -65.5t157.5 65.5t65.5 157.5q0 93 -65.5 158.5t-157.5 65.5zM1163 574q13 -27 15 -49.5
+t-4.5 -40.5t-26.5 -38.5t-42.5 -37t-61.5 -41.5q-115 -73 -315 -94l73 -72l267 -267q30 -31 30 -74t-30 -73l-12 -13q-31 -30 -74 -30t-74 30q-67 68 -267 268l-267 -268q-31 -30 -74 -30t-73 30l-12 13q-31 30 -31 73t31 74l267 267l72 72q-203 21 -317 94
+q-39 25 -61.5 41.5t-42.5 37t-26.5 38.5t-4.5 40.5t15 49.5q10 20 28 35t42 22t56 -2t65 -35q5 -4 15 -11t43 -24.5t69 -30.5t92 -24t113 -11q91 0 174 25.5t120 50.5l38 25q33 26 65 35t56 2t42 -22t28 -35z" />
+    <glyph glyph-name="_574" unicode="&#xf264;" 
+d="M927 956q0 -66 -46.5 -112.5t-112.5 -46.5t-112.5 46.5t-46.5 112.5t46.5 112.5t112.5 46.5t112.5 -46.5t46.5 -112.5zM1141 593q-10 20 -28 32t-47.5 9.5t-60.5 -27.5q-10 -8 -29 -20t-81 -32t-127 -20t-124 18t-86 36l-27 18q-31 25 -60.5 27.5t-47.5 -9.5t-28 -32
+q-22 -45 -2 -74.5t87 -73.5q83 -53 226 -67l-51 -52q-142 -142 -191 -190q-22 -22 -22 -52.5t22 -52.5l9 -9q22 -22 52.5 -22t52.5 22l191 191q114 -115 191 -191q22 -22 52.5 -22t52.5 22l9 9q22 22 22 52.5t-22 52.5l-191 190l-52 52q141 14 225 67q67 44 87 73.5t-2 74.5
+zM1092 956q0 134 -95 229t-229 95t-229 -95t-95 -229t95 -229t229 -95t229 95t95 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="_575" unicode="&#xf265;" horiz-adv-x="1720" 
+d="M1565 1408q65 0 110 -45.5t45 -110.5v-519q0 -176 -68 -336t-182.5 -275t-274 -182.5t-334.5 -67.5q-176 0 -335.5 67.5t-274.5 182.5t-183 275t-68 336v519q0 64 46 110t110 46h1409zM861 344q47 0 82 33l404 388q37 35 37 85q0 49 -34.5 83.5t-83.5 34.5q-47 0 -82 -33
+l-323 -310l-323 310q-35 33 -81 33q-49 0 -83.5 -34.5t-34.5 -83.5q0 -51 36 -85l405 -388q33 -33 81 -33z" />
+    <glyph glyph-name="_576" unicode="&#xf266;" horiz-adv-x="2304" 
+d="M1494 -103l-295 695q-25 -49 -158.5 -305.5t-198.5 -389.5q-1 -1 -27.5 -0.5t-26.5 1.5q-82 193 -255.5 587t-259.5 596q-21 50 -66.5 107.5t-103.5 100.5t-102 43q0 5 -0.5 24t-0.5 27h583v-50q-39 -2 -79.5 -16t-66.5 -43t-10 -64q26 -59 216.5 -499t235.5 -540
+q31 61 140 266.5t131 247.5q-19 39 -126 281t-136 295q-38 69 -201 71v50l513 -1v-47q-60 -2 -93.5 -25t-12.5 -69q33 -70 87 -189.5t86 -187.5q110 214 173 363q24 55 -10 79.5t-129 26.5q1 7 1 25v24q64 0 170.5 0.5t180 1t92.5 0.5v-49q-62 -2 -119 -33t-90 -81
+l-213 -442q13 -33 127.5 -290t121.5 -274l441 1017q-14 38 -49.5 62.5t-65 31.5t-55.5 8v50l460 -4l1 -2l-1 -44q-139 -4 -201 -145q-526 -1216 -559 -1291h-49z" />
+    <glyph glyph-name="_577" unicode="&#xf267;" horiz-adv-x="1792" 
+d="M949 643q0 -26 -16.5 -45t-41.5 -19q-26 0 -45 16.5t-19 41.5q0 26 17 45t42 19t44 -16.5t19 -41.5zM964 585l350 581q-9 -8 -67.5 -62.5t-125.5 -116.5t-136.5 -127t-117 -110.5t-50.5 -51.5l-349 -580q7 7 67 62t126 116.5t136 127t117 111t50 50.5zM1611 640
+q0 -201 -104 -371q-3 2 -17 11t-26.5 16.5t-16.5 7.5q-13 0 -13 -13q0 -10 59 -44q-74 -112 -184.5 -190.5t-241.5 -110.5l-16 67q-1 10 -15 10q-5 0 -8 -5.5t-2 -9.5l16 -68q-72 -15 -146 -15q-199 0 -372 105q1 2 13 20.5t21.5 33.5t9.5 19q0 13 -13 13q-6 0 -17 -14.5
+t-22.5 -34.5t-13.5 -23q-113 75 -192 187.5t-110 244.5l69 15q10 3 10 15q0 5 -5.5 8t-10.5 2l-68 -15q-14 72 -14 139q0 206 109 379q2 -1 18.5 -12t30 -19t17.5 -8q13 0 13 12q0 6 -12.5 15.5t-32.5 21.5l-20 12q77 112 189 189t244 107l15 -67q2 -10 15 -10q5 0 8 5.5
+t2 10.5l-15 66q71 13 134 13q204 0 379 -109q-39 -56 -39 -65q0 -13 12 -13q11 0 48 64q111 -75 187.5 -186t107.5 -241l-56 -12q-10 -2 -10 -16q0 -5 5.5 -8t9.5 -2l57 13q14 -72 14 -140zM1696 640q0 163 -63.5 311t-170.5 255t-255 170.5t-311 63.5t-311 -63.5
+t-255 -170.5t-170.5 -255t-63.5 -311t63.5 -311t170.5 -255t255 -170.5t311 -63.5t311 63.5t255 170.5t170.5 255t63.5 311zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191
+t191 -286t71 -348z" />
+    <glyph glyph-name="_578" unicode="&#xf268;" horiz-adv-x="1792" 
+d="M893 1536q240 2 451 -120q232 -134 352 -372l-742 39q-160 9 -294 -74.5t-185 -229.5l-276 424q128 159 311 245.5t383 87.5zM146 1131l337 -663q72 -143 211 -217t293 -45l-230 -451q-212 33 -385 157.5t-272.5 316t-99.5 411.5q0 267 146 491zM1732 962
+q58 -150 59.5 -310.5t-48.5 -306t-153 -272t-246 -209.5q-230 -133 -498 -119l405 623q88 131 82.5 290.5t-106.5 277.5zM896 942q125 0 213.5 -88.5t88.5 -213.5t-88.5 -213.5t-213.5 -88.5t-213.5 88.5t-88.5 213.5t88.5 213.5t213.5 88.5z" />
+    <glyph glyph-name="_579" unicode="&#xf269;" horiz-adv-x="1792" 
+d="M903 -256q-283 0 -504.5 150.5t-329.5 398.5q-58 131 -67 301t26 332.5t111 312t179 242.5l-11 -281q11 14 68 15.5t70 -15.5q42 81 160.5 138t234.5 59q-54 -45 -119.5 -148.5t-58.5 -163.5q25 -8 62.5 -13.5t63 -7.5t68 -4t50.5 -3q15 -5 9.5 -45.5t-30.5 -75.5
+q-5 -7 -16.5 -18.5t-56.5 -35.5t-101 -34l15 -189l-139 67q-18 -43 -7.5 -81.5t36 -66.5t65.5 -41.5t81 -6.5q51 9 98 34.5t83.5 45t73.5 17.5q61 -4 89.5 -33t19.5 -65q-1 -2 -2.5 -5.5t-8.5 -12.5t-18 -15.5t-31.5 -10.5t-46.5 -1q-60 -95 -144.5 -135.5t-209.5 -29.5
+q74 -61 162.5 -82.5t168.5 -6t154.5 52t128 87.5t80.5 104q43 91 39 192.5t-37.5 188.5t-78.5 125q87 -38 137 -79.5t77 -112.5q15 170 -57.5 343t-209.5 284q265 -77 412 -279.5t151 -517.5q2 -127 -40.5 -255t-123.5 -238t-189 -196t-247.5 -135.5t-288.5 -49.5z" />
+    <glyph glyph-name="_580" unicode="&#xf26a;" horiz-adv-x="1792" 
+d="M1493 1308q-165 110 -359 110q-155 0 -293 -73t-240 -200q-75 -93 -119.5 -218t-48.5 -266v-42q4 -141 48.5 -266t119.5 -218q102 -127 240 -200t293 -73q194 0 359 110q-121 -108 -274.5 -168t-322.5 -60q-29 0 -43 1q-175 8 -333 82t-272 193t-181 281t-67 339
+q0 182 71 348t191 286t286 191t348 71h3q168 -1 320.5 -60.5t273.5 -167.5zM1792 640q0 -192 -77 -362.5t-213 -296.5q-104 -63 -222 -63q-137 0 -255 84q154 56 253.5 233t99.5 405q0 227 -99 404t-253 234q119 83 254 83q119 0 226 -65q135 -125 210.5 -295t75.5 -361z
+" />
+    <glyph glyph-name="_581" unicode="&#xf26b;" horiz-adv-x="1792" 
+d="M1792 599q0 -56 -7 -104h-1151q0 -146 109.5 -244.5t257.5 -98.5q99 0 185.5 46.5t136.5 130.5h423q-56 -159 -170.5 -281t-267.5 -188.5t-321 -66.5q-187 0 -356 83q-228 -116 -394 -116q-237 0 -237 263q0 115 45 275q17 60 109 229q199 360 475 606
+q-184 -79 -427 -354q63 274 283.5 449.5t501.5 175.5q30 0 45 -1q255 117 433 117q64 0 116 -13t94.5 -40.5t66.5 -76.5t24 -115q0 -116 -75 -286q101 -182 101 -390zM1722 1239q0 83 -53 132t-137 49q-108 0 -254 -70q121 -47 222.5 -131.5t170.5 -195.5q51 135 51 216z
+M128 2q0 -86 48.5 -132.5t134.5 -46.5q115 0 266 83q-122 72 -213.5 183t-137.5 245q-98 -205 -98 -332zM632 715h728q-5 142 -113 237t-251 95q-144 0 -251.5 -95t-112.5 -237z" />
+    <glyph glyph-name="_582" unicode="&#xf26c;" horiz-adv-x="2048" 
+d="M1792 288v960q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1248v-960q0 -66 -47 -113t-113 -47h-736v-128h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23
+v64q0 14 9 23t23 9h352v128h-736q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="_583" unicode="&#xf26d;" horiz-adv-x="1792" 
+d="M138 1408h197q-70 -64 -126 -149q-36 -56 -59 -115t-30 -125.5t-8.5 -120t10.5 -132t21 -126t28 -136.5q4 -19 6 -28q51 -238 81 -329q57 -171 152 -275h-272q-48 0 -82 34t-34 82v1304q0 48 34 82t82 34zM1346 1408h308q48 0 82 -34t34 -82v-1304q0 -48 -34 -82t-82 -34
+h-178q212 210 196 565l-469 -101q-2 -45 -12 -82t-31 -72t-59.5 -59.5t-93.5 -36.5q-123 -26 -199 40q-32 27 -53 61t-51.5 129t-64.5 258q-35 163 -45.5 263t-5.5 139t23 77q20 41 62.5 73t102.5 45q45 12 83.5 6.5t67 -17t54 -35t43 -48t34.5 -56.5l468 100
+q-68 175 -180 287z" />
+    <glyph glyph-name="_584" unicode="&#xf26e;" 
+d="M1401 -11l-6 -6q-113 -113 -259 -175q-154 -64 -317 -64q-165 0 -317 64q-148 63 -259 175q-113 112 -175 258q-42 103 -54 189q-4 28 48 36q51 8 56 -20q1 -1 1 -4q18 -90 46 -159q50 -124 152 -226q98 -98 226 -152q132 -56 276 -56q143 0 276 56q128 55 225 152l6 6
+q10 10 25 6q12 -3 33 -22q36 -37 17 -58zM929 604l-66 -66l63 -63q21 -21 -7 -49q-17 -17 -32 -17q-10 0 -19 10l-62 61l-66 -66q-5 -5 -15 -5q-15 0 -31 16l-2 2q-18 15 -18 29q0 7 8 17l66 65l-66 66q-16 16 14 45q18 18 31 18q6 0 13 -5l65 -66l65 65q18 17 48 -13
+q27 -27 11 -44zM1400 547q0 -118 -46 -228q-45 -105 -126 -186q-80 -80 -187 -126t-228 -46t-228 46t-187 126q-82 82 -125 186q-15 33 -15 40h-1q-9 27 43 44q50 16 60 -12q37 -99 97 -167h1v339v2q3 136 102 232q105 103 253 103q147 0 251 -103t104 -249
+q0 -147 -104.5 -251t-250.5 -104q-58 0 -112 16q-28 11 -13 61q16 51 44 43l14 -3q14 -3 33 -6t30 -3q104 0 176 71.5t72 174.5q0 101 -72 171q-71 71 -175 71q-107 0 -178 -80q-64 -72 -64 -160v-413q110 -67 242 -67q96 0 185 36.5t156 103.5t103.5 155t36.5 183
+q0 198 -141 339q-140 140 -339 140q-200 0 -340 -140q-53 -53 -77 -87l-2 -2q-8 -11 -13 -15.5t-21.5 -9.5t-38.5 3q-21 5 -36.5 16.5t-15.5 26.5v680q0 15 10.5 26.5t27.5 11.5h877q30 0 30 -55t-30 -55h-811v-483h1q40 42 102 84t108 61q109 46 231 46q121 0 228 -46
+t187 -126q81 -81 126 -186q46 -112 46 -229zM1369 1128q9 -8 9 -18t-5.5 -18t-16.5 -21q-26 -26 -39 -26q-9 0 -16 7q-106 91 -207 133q-128 56 -276 56q-133 0 -262 -49q-27 -10 -45 37q-9 25 -8 38q3 16 16 20q130 57 299 57q164 0 316 -64q137 -58 235 -152z" />
+    <glyph glyph-name="_585" unicode="&#xf270;" horiz-adv-x="1792" 
+d="M1551 60q15 6 26 3t11 -17.5t-15 -33.5q-13 -16 -44 -43.5t-95.5 -68t-141 -74t-188 -58t-229.5 -24.5q-119 0 -238 31t-209 76.5t-172.5 104t-132.5 105t-84 87.5q-8 9 -10 16.5t1 12t8 7t11.5 2t11.5 -4.5q192 -117 300 -166q389 -176 799 -90q190 40 391 135z
+M1758 175q11 -16 2.5 -69.5t-28.5 -102.5q-34 -83 -85 -124q-17 -14 -26 -9t0 24q21 45 44.5 121.5t6.5 98.5q-5 7 -15.5 11.5t-27 6t-29.5 2.5t-35 0t-31.5 -2t-31 -3t-22.5 -2q-6 -1 -13 -1.5t-11 -1t-8.5 -1t-7 -0.5h-5.5h-4.5t-3 0.5t-2 1.5l-1.5 3q-6 16 47 40t103 30
+q46 7 108 1t76 -24zM1364 618q0 -31 13.5 -64t32 -58t37.5 -46t33 -32l13 -11l-227 -224q-40 37 -79 75.5t-58 58.5l-19 20q-11 11 -25 33q-38 -59 -97.5 -102.5t-127.5 -63.5t-140 -23t-137.5 21t-117.5 65.5t-83 113t-31 162.5q0 84 28 154t72 116.5t106.5 83t122.5 57
+t130 34.5t119.5 18.5t99.5 6.5v127q0 65 -21 97q-34 53 -121 53q-6 0 -16.5 -1t-40.5 -12t-56 -29.5t-56 -59.5t-48 -96l-294 27q0 60 22 119t67 113t108 95t151.5 65.5t190.5 24.5q100 0 181 -25t129.5 -61.5t81 -83t45 -86t12.5 -73.5v-589zM692 597q0 -86 70 -133
+q66 -44 139 -22q84 25 114 123q14 45 14 101v162q-59 -2 -111 -12t-106.5 -33.5t-87 -71t-32.5 -114.5z" />
+    <glyph glyph-name="_586" unicode="&#xf271;" horiz-adv-x="1792" 
+d="M1536 1280q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128zM1152 1376v-288q0 -14 9 -23t23 -9
+h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 1376v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM1536 -128v1024h-1408v-1024h1408zM896 448h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224
+v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224z" />
+    <glyph glyph-name="_587" unicode="&#xf272;" horiz-adv-x="1792" 
+d="M1152 416v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23
+t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47
+t47 -113v-96h128q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="_588" unicode="&#xf273;" horiz-adv-x="1792" 
+d="M1111 151l-46 -46q-9 -9 -22 -9t-23 9l-188 189l-188 -189q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22t9 23l189 188l-189 188q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l188 -188l188 188q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23l-188 -188l188 -188q9 -10 9 -23t-9 -22z
+M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280
+q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="_589" unicode="&#xf274;" horiz-adv-x="1792" 
+d="M1303 572l-512 -512q-10 -9 -23 -9t-23 9l-288 288q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l220 -220l444 444q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23
+t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47
+t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
+    <glyph glyph-name="_590" unicode="&#xf275;" horiz-adv-x="1792" 
+d="M448 1536q26 0 45 -19t19 -45v-891l536 429q17 14 40 14q26 0 45 -19t19 -45v-379l536 429q17 14 40 14q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h384z" />
+    <glyph glyph-name="_591" unicode="&#xf276;" horiz-adv-x="1024" 
+d="M512 448q66 0 128 15v-655q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v655q62 -15 128 -15zM512 1536q212 0 362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362t150 362t362 150zM512 1312q14 0 23 9t9 23t-9 23t-23 9q-146 0 -249 -103t-103 -249
+q0 -14 9 -23t23 -9t23 9t9 23q0 119 84.5 203.5t203.5 84.5z" />
+    <glyph glyph-name="_592" unicode="&#xf277;" horiz-adv-x="1792" 
+d="M1745 1239q10 -10 10 -23t-10 -23l-141 -141q-28 -28 -68 -28h-1344q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h576v64q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-64h512q40 0 68 -28zM768 320h256v-512q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v512zM1600 768
+q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1344q-40 0 -68 28l-141 141q-10 10 -10 23t10 23l141 141q28 28 68 28h512v192h256v-192h576z" />
+    <glyph glyph-name="_593" unicode="&#xf278;" horiz-adv-x="2048" 
+d="M2020 1525q28 -20 28 -53v-1408q0 -20 -11 -36t-29 -23l-640 -256q-24 -11 -48 0l-616 246l-616 -246q-10 -5 -24 -5q-19 0 -36 11q-28 20 -28 53v1408q0 20 11 36t29 23l640 256q24 11 48 0l616 -246l616 246q32 13 60 -6zM736 1390v-1270l576 -230v1270zM128 1173
+v-1270l544 217v1270zM1920 107v1270l-544 -217v-1270z" />
+    <glyph glyph-name="_594" unicode="&#xf279;" horiz-adv-x="1792" 
+d="M512 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472q0 20 17 28l480 256q7 4 15 4zM1760 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472
+q0 20 17 28l480 256q7 4 15 4zM640 1536q8 0 14 -3l512 -256q18 -10 18 -29v-1472q0 -13 -9.5 -22.5t-22.5 -9.5q-8 0 -14 3l-512 256q-18 10 -18 29v1472q0 13 9.5 22.5t22.5 9.5z" />
+    <glyph glyph-name="_595" unicode="&#xf27a;" horiz-adv-x="1792" 
+d="M640 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 640q0 53 -37.5 90.5t-90.5 37.5
+t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-110 0 -211 18q-173 -173 -435 -229q-52 -10 -86 -13q-12 -1 -22 6t-13 18q-4 15 20 37q5 5 23.5 21.5t25.5 23.5t23.5 25.5t24 31.5t20.5 37
+t20 48t14.5 57.5t12.5 72.5q-146 90 -229.5 216.5t-83.5 269.5q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
+    <glyph glyph-name="_596" unicode="&#xf27b;" horiz-adv-x="1792" 
+d="M640 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 -53 -37.5 -90.5t-90.5 -37.5
+t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5
+t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51
+t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 130 71 248.5t191 204.5t286 136.5t348 50.5t348 -50.5t286 -136.5t191 -204.5t71 -248.5z" />
+    <glyph glyph-name="_597" unicode="&#xf27c;" horiz-adv-x="1024" 
+d="M512 345l512 295v-591l-512 -296v592zM0 640v-591l512 296zM512 1527v-591l-512 -296v591zM512 936l512 295v-591z" />
+    <glyph glyph-name="_598" unicode="&#xf27d;" horiz-adv-x="1792" 
+d="M1709 1018q-10 -236 -332 -651q-333 -431 -562 -431q-142 0 -240 263q-44 160 -132 482q-72 262 -157 262q-18 0 -127 -76l-77 98q24 21 108 96.5t130 115.5q156 138 241 146q95 9 153 -55.5t81 -203.5q44 -287 66 -373q55 -249 120 -249q51 0 154 161q101 161 109 246
+q13 139 -109 139q-57 0 -121 -26q120 393 459 382q251 -8 236 -326z" />
+    <glyph glyph-name="f27e" unicode="&#xf27e;" 
+d="M0 1408h1536v-1536h-1536v1536zM1085 293l-221 631l221 297h-634l221 -297l-221 -631l317 -304z" />
+    <glyph glyph-name="uniF280" unicode="&#xf280;" 
+d="M0 1408h1536v-1536h-1536v1536zM908 1088l-12 -33l75 -83l-31 -114l25 -25l107 57l107 -57l25 25l-31 114l75 83l-12 33h-95l-53 96h-32l-53 -96h-95zM641 925q32 0 44.5 -16t11.5 -63l174 21q0 55 -17.5 92.5t-50.5 56t-69 25.5t-85 7q-133 0 -199 -57.5t-66 -182.5v-72
+h-96v-128h76q20 0 20 -8v-382q0 -14 -5 -20t-18 -7l-73 -7v-88h448v86l-149 14q-6 1 -8.5 1.5t-3.5 2.5t-0.5 4t1 7t0.5 10v387h191l38 128h-231q-6 0 -2 6t4 9v80q0 27 1.5 40.5t7.5 28t19.5 20t36.5 5.5zM1248 96v86l-54 9q-7 1 -9.5 2.5t-2.5 3t1 7.5t1 12v520h-275
+l-23 -101l83 -22q23 -7 23 -27v-370q0 -14 -6 -18.5t-20 -6.5l-70 -9v-86h352z" />
+    <glyph glyph-name="uniF281" unicode="&#xf281;" horiz-adv-x="1792" 
+d="M1792 690q0 -58 -29.5 -105.5t-79.5 -72.5q12 -46 12 -96q0 -155 -106.5 -287t-290.5 -208.5t-400 -76.5t-399.5 76.5t-290 208.5t-106.5 287q0 47 11 94q-51 25 -82 73.5t-31 106.5q0 82 58 140.5t141 58.5q85 0 145 -63q218 152 515 162l116 521q3 13 15 21t26 5
+l369 -81q18 37 54 59.5t79 22.5q62 0 106 -43.5t44 -105.5t-44 -106t-106 -44t-105.5 43.5t-43.5 105.5l-334 74l-104 -472q300 -9 519 -160q58 61 143 61q83 0 141 -58.5t58 -140.5zM418 491q0 -62 43.5 -106t105.5 -44t106 44t44 106t-44 105.5t-106 43.5q-61 0 -105 -44
+t-44 -105zM1228 136q11 11 11 26t-11 26q-10 10 -25 10t-26 -10q-41 -42 -121 -62t-160 -20t-160 20t-121 62q-11 10 -26 10t-25 -10q-11 -10 -11 -25.5t11 -26.5q43 -43 118.5 -68t122.5 -29.5t91 -4.5t91 4.5t122.5 29.5t118.5 68zM1225 341q62 0 105.5 44t43.5 106
+q0 61 -44 105t-105 44q-62 0 -106 -43.5t-44 -105.5t44 -106t106 -44z" />
+    <glyph glyph-name="_602" unicode="&#xf282;" horiz-adv-x="1792" 
+d="M69 741h1q16 126 58.5 241.5t115 217t167.5 176t223.5 117.5t276.5 43q231 0 414 -105.5t294 -303.5q104 -187 104 -442v-188h-1125q1 -111 53.5 -192.5t136.5 -122.5t189.5 -57t213 -3t208 46.5t173.5 84.5v-377q-92 -55 -229.5 -92t-312.5 -38t-316 53
+q-189 73 -311.5 249t-124.5 372q-3 242 111 412t325 268q-48 -60 -78 -125.5t-46 -159.5h635q8 77 -8 140t-47 101.5t-70.5 66.5t-80.5 41t-75 20.5t-56 8.5l-22 1q-135 -5 -259.5 -44.5t-223.5 -104.5t-176 -140.5t-138 -163.5z" />
+    <glyph glyph-name="_603" unicode="&#xf283;" horiz-adv-x="2304" 
+d="M0 32v608h2304v-608q0 -66 -47 -113t-113 -47h-1984q-66 0 -113 47t-47 113zM640 256v-128h384v128h-384zM256 256v-128h256v128h-256zM2144 1408q66 0 113 -47t47 -113v-224h-2304v224q0 66 47 113t113 47h1984z" />
+    <glyph glyph-name="_604" unicode="&#xf284;" horiz-adv-x="1792" 
+d="M1584 246l-218 111q-74 -120 -196.5 -189t-263.5 -69q-147 0 -271 72t-196 196t-72 270q0 110 42.5 209.5t115 172t172 115t209.5 42.5q131 0 247.5 -60.5t192.5 -168.5l215 125q-110 169 -286.5 265t-378.5 96q-161 0 -308 -63t-253 -169t-169 -253t-63 -308t63 -308
+t169 -253t253 -169t308 -63q213 0 397.5 107t290.5 292zM1030 643l693 -352q-116 -253 -334.5 -400t-492.5 -147q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71q260 0 470.5 -133.5t335.5 -366.5zM1543 640h-39v-160h-96v352h136q32 0 54.5 -20
+t28.5 -48t1 -56t-27.5 -48t-57.5 -20z" />
+    <glyph glyph-name="uniF285" unicode="&#xf285;" horiz-adv-x="1792" 
+d="M1427 827l-614 386l92 151h855zM405 562l-184 116v858l1183 -743zM1424 697l147 -95v-858l-532 335zM1387 718l-500 -802h-855l356 571z" />
+    <glyph glyph-name="uniF286" unicode="&#xf286;" horiz-adv-x="1792" 
+d="M640 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1152 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1664 496v-752h-640v320q0 80 -56 136t-136 56t-136 -56t-56 -136v-320h-640v752q0 16 16 16h96
+q16 0 16 -16v-112h128v624q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 6 2.5 9.5t8.5 5t9.5 2t11.5 0t9 -0.5v391q-32 15 -32 50q0 23 16.5 39t38.5 16t38.5 -16t16.5 -39q0 -35 -32 -50v-17q45 10 83 10q21 0 59.5 -7.5t54.5 -7.5
+q17 0 47 7.5t37 7.5q16 0 16 -16v-210q0 -15 -35 -21.5t-62 -6.5q-18 0 -54.5 7.5t-55.5 7.5q-40 0 -90 -12v-133q1 0 9 0.5t11.5 0t9.5 -2t8.5 -5t2.5 -9.5v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-624h128v112q0 16 16 16h96
+q16 0 16 -16z" />
+    <glyph glyph-name="_607" unicode="&#xf287;" horiz-adv-x="2304" 
+d="M2288 731q16 -8 16 -27t-16 -27l-320 -192q-8 -5 -16 -5q-9 0 -16 4q-16 10 -16 28v128h-858q37 -58 83 -165q16 -37 24.5 -55t24 -49t27 -47t27 -34t31.5 -26t33 -8h96v96q0 14 9 23t23 9h320q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v96h-96
+q-32 0 -61 10t-51 23.5t-45 40.5t-37 46t-33.5 57t-28.5 57.5t-28 60.5q-23 53 -37 81.5t-36 65t-44.5 53.5t-46.5 17h-360q-22 -84 -91 -138t-157 -54q-106 0 -181 75t-75 181t75 181t181 75q88 0 157 -54t91 -138h104q24 0 46.5 17t44.5 53.5t36 65t37 81.5q19 41 28 60.5
+t28.5 57.5t33.5 57t37 46t45 40.5t51 23.5t61 10h107q21 57 70 92.5t111 35.5q80 0 136 -56t56 -136t-56 -136t-136 -56q-62 0 -111 35.5t-70 92.5h-107q-17 0 -33 -8t-31.5 -26t-27 -34t-27 -47t-24 -49t-24.5 -55q-46 -107 -83 -165h1114v128q0 18 16 28t32 -1z" />
+    <glyph glyph-name="_608" unicode="&#xf288;" horiz-adv-x="1792" 
+d="M1150 774q0 -56 -39.5 -95t-95.5 -39h-253v269h253q56 0 95.5 -39.5t39.5 -95.5zM1329 774q0 130 -91.5 222t-222.5 92h-433v-896h180v269h253q130 0 222 91.5t92 221.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348
+t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="_609" unicode="&#xf289;" horiz-adv-x="2304" 
+d="M1645 438q0 59 -34 106.5t-87 68.5q-7 -45 -23 -92q-7 -24 -27.5 -38t-44.5 -14q-12 0 -24 3q-31 10 -45 38.5t-4 58.5q23 71 23 143q0 123 -61 227.5t-166 165.5t-228 61q-134 0 -247 -73t-167 -194q108 -28 188 -106q22 -23 22 -55t-22 -54t-54 -22t-55 22
+q-75 75 -180 75q-106 0 -181 -74.5t-75 -180.5t75 -180.5t181 -74.5h1046q79 0 134.5 55.5t55.5 133.5zM1798 438q0 -142 -100.5 -242t-242.5 -100h-1046q-169 0 -289 119.5t-120 288.5q0 153 100 267t249 136q62 184 221 298t354 114q235 0 408.5 -158.5t196.5 -389.5
+q116 -25 192.5 -118.5t76.5 -214.5zM2048 438q0 -175 -97 -319q-23 -33 -64 -33q-24 0 -43 13q-26 17 -32 48.5t12 57.5q71 104 71 233t-71 233q-18 26 -12 57t32 49t57.5 11.5t49.5 -32.5q97 -142 97 -318zM2304 438q0 -244 -134 -443q-23 -34 -64 -34q-23 0 -42 13
+q-26 18 -32.5 49t11.5 57q108 164 108 358q0 195 -108 357q-18 26 -11.5 57.5t32.5 48.5q26 18 57 12t49 -33q134 -198 134 -442z" />
+    <glyph glyph-name="_610" unicode="&#xf28a;" 
+d="M1500 -13q0 -89 -63 -152.5t-153 -63.5t-153.5 63.5t-63.5 152.5q0 90 63.5 153.5t153.5 63.5t153 -63.5t63 -153.5zM1267 268q-115 -15 -192.5 -102.5t-77.5 -205.5q0 -74 33 -138q-146 -78 -379 -78q-109 0 -201 21t-153.5 54.5t-110.5 76.5t-76 85t-44.5 83
+t-23.5 66.5t-6 39.5q0 19 4.5 42.5t18.5 56t36.5 58t64 43.5t94.5 18t94 -17.5t63 -41t35.5 -53t17.5 -49t4 -33.5q0 -34 -23 -81q28 -27 82 -42t93 -17l40 -1q115 0 190 51t75 133q0 26 -9 48.5t-31.5 44.5t-49.5 41t-74 44t-93.5 47.5t-119.5 56.5q-28 13 -43 20
+q-116 55 -187 100t-122.5 102t-72 125.5t-20.5 162.5q0 78 20.5 150t66 137.5t112.5 114t166.5 77t221.5 28.5q120 0 220 -26t164.5 -67t109.5 -94t64 -105.5t19 -103.5q0 -46 -15 -82.5t-36.5 -58t-48.5 -36t-49 -19.5t-39 -5h-8h-32t-39 5t-44 14t-41 28t-37 46t-24 70.5
+t-10 97.5q-15 16 -59 25.5t-81 10.5l-37 1q-68 0 -117.5 -31t-70.5 -70t-21 -76q0 -24 5 -43t24 -46t53 -51t97 -53.5t150 -58.5q76 -25 138.5 -53.5t109 -55.5t83 -59t60.5 -59.5t41 -62.5t26.5 -62t14.5 -63.5t6 -62t1 -62.5z" />
+    <glyph glyph-name="_611" unicode="&#xf28b;" 
+d="M704 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1152 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103
+t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="_612" unicode="&#xf28c;" 
+d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273
+t73 -273t198 -198t273 -73zM864 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192z" />
+    <glyph glyph-name="_613" unicode="&#xf28d;" 
+d="M1088 352v576q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
+t103 -385.5z" />
+    <glyph glyph-name="_614" unicode="&#xf28e;" 
+d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273
+t73 -273t198 -198t273 -73zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h576q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-576z" />
+    <glyph glyph-name="_615" unicode="&#xf290;" horiz-adv-x="1792" 
+d="M1757 128l35 -313q3 -28 -16 -50q-19 -21 -48 -21h-1664q-29 0 -48 21q-19 22 -16 50l35 313h1722zM1664 967l86 -775h-1708l86 775q3 24 21 40.5t43 16.5h256v-128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5v128h384v-128q0 -53 37.5 -90.5t90.5 -37.5
+t90.5 37.5t37.5 90.5v128h256q25 0 43 -16.5t21 -40.5zM1280 1152v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
+    <glyph glyph-name="_616" unicode="&#xf291;" horiz-adv-x="2048" 
+d="M1920 768q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5h-15l-115 -662q-8 -46 -44 -76t-82 -30h-1280q-46 0 -82 30t-44 76l-115 662h-15q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5h1792zM485 -32q26 2 43.5 22.5t15.5 46.5l-32 416q-2 26 -22.5 43.5
+t-46.5 15.5t-43.5 -22.5t-15.5 -46.5l32 -416q2 -25 20.5 -42t43.5 -17h5zM896 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1280 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1632 27l32 416
+q2 26 -15.5 46.5t-43.5 22.5t-46.5 -15.5t-22.5 -43.5l-32 -416q-2 -26 15.5 -46.5t43.5 -22.5h5q25 0 43.5 17t20.5 42zM476 1244l-93 -412h-132l101 441q19 88 89 143.5t160 55.5h167q0 26 19 45t45 19h384q26 0 45 -19t19 -45h167q90 0 160 -55.5t89 -143.5l101 -441
+h-132l-93 412q-11 44 -45.5 72t-79.5 28h-167q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45h-167q-45 0 -79.5 -28t-45.5 -72z" />
+    <glyph glyph-name="_617" unicode="&#xf292;" horiz-adv-x="1792" 
+d="M991 512l64 256h-254l-64 -256h254zM1759 1016l-56 -224q-7 -24 -31 -24h-327l-64 -256h311q15 0 25 -12q10 -14 6 -28l-56 -224q-5 -24 -31 -24h-327l-81 -328q-7 -24 -31 -24h-224q-16 0 -26 12q-9 12 -6 28l78 312h-254l-81 -328q-7 -24 -31 -24h-225q-15 0 -25 12
+q-9 12 -6 28l78 312h-311q-15 0 -25 12q-9 12 -6 28l56 224q7 24 31 24h327l64 256h-311q-15 0 -25 12q-10 14 -6 28l56 224q5 24 31 24h327l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h254l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h311
+q15 0 25 -12q9 -12 6 -28z" />
+    <glyph glyph-name="_618" unicode="&#xf293;" 
+d="M841 483l148 -148l-149 -149zM840 1094l149 -149l-148 -148zM710 -130l464 464l-306 306l306 306l-464 464v-611l-255 255l-93 -93l320 -321l-320 -321l93 -93l255 255v-611zM1429 640q0 -209 -32 -365.5t-87.5 -257t-140.5 -162.5t-181.5 -86.5t-219.5 -24.5
+t-219.5 24.5t-181.5 86.5t-140.5 162.5t-87.5 257t-32 365.5t32 365.5t87.5 257t140.5 162.5t181.5 86.5t219.5 24.5t219.5 -24.5t181.5 -86.5t140.5 -162.5t87.5 -257t32 -365.5z" />
+    <glyph glyph-name="_619" unicode="&#xf294;" horiz-adv-x="1024" 
+d="M596 113l173 172l-173 172v-344zM596 823l173 172l-173 172v-344zM628 640l356 -356l-539 -540v711l-297 -296l-108 108l372 373l-372 373l108 108l297 -296v711l539 -540z" />
+    <glyph glyph-name="_620" unicode="&#xf295;" 
+d="M1280 256q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM512 1024q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5
+t112.5 -271.5zM1440 1344q0 -20 -13 -38l-1056 -1408q-19 -26 -51 -26h-160q-26 0 -45 19t-19 45q0 20 13 38l1056 1408q19 26 51 26h160q26 0 45 -19t19 -45zM768 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5
+t271.5 -112.5t112.5 -271.5z" />
+    <glyph glyph-name="_621" unicode="&#xf296;" horiz-adv-x="1792" 
+d="M104 830l792 -1015l-868 630q-18 13 -25 34.5t0 42.5l101 308v0zM566 830h660l-330 -1015v0zM368 1442l198 -612h-462l198 612q8 23 33 23t33 -23zM1688 830l101 -308q7 -21 0 -42.5t-25 -34.5l-868 -630l792 1015v0zM1688 830h-462l198 612q8 23 33 23t33 -23z" />
+    <glyph glyph-name="_622" unicode="&#xf297;" horiz-adv-x="1792" 
+d="M384 704h160v224h-160v-224zM1221 372v92q-104 -36 -243 -38q-135 -1 -259.5 46.5t-220.5 122.5l1 -96q88 -80 212 -128.5t272 -47.5q129 0 238 49zM640 704h640v224h-640v-224zM1792 736q0 -187 -99 -352q89 -102 89 -229q0 -157 -129.5 -268t-313.5 -111
+q-122 0 -225 52.5t-161 140.5q-19 -1 -57 -1t-57 1q-58 -88 -161 -140.5t-225 -52.5q-184 0 -313.5 111t-129.5 268q0 127 89 229q-99 165 -99 352q0 209 120 385.5t326.5 279.5t449.5 103t449.5 -103t326.5 -279.5t120 -385.5z" />
+    <glyph glyph-name="_623" unicode="&#xf298;" 
+d="M515 625v-128h-252v128h252zM515 880v-127h-252v127h252zM1273 369v-128h-341v128h341zM1273 625v-128h-672v128h672zM1273 880v-127h-672v127h672zM1408 20v1240q0 8 -6 14t-14 6h-32l-378 -256l-210 171l-210 -171l-378 256h-32q-8 0 -14 -6t-6 -14v-1240q0 -8 6 -14
+t14 -6h1240q8 0 14 6t6 14zM553 1130l185 150h-406zM983 1130l221 150h-406zM1536 1260v-1240q0 -62 -43 -105t-105 -43h-1240q-62 0 -105 43t-43 105v1240q0 62 43 105t105 43h1240q62 0 105 -43t43 -105z" />
+    <glyph glyph-name="_624" unicode="&#xf299;" horiz-adv-x="1792" 
+d="M896 720q-104 196 -160 278q-139 202 -347 318q-34 19 -70 36q-89 40 -94 32t34 -38l39 -31q62 -43 112.5 -93.5t94.5 -116.5t70.5 -113t70.5 -131q9 -17 13 -25q44 -84 84 -153t98 -154t115.5 -150t131 -123.5t148.5 -90.5q153 -66 154 -60q1 3 -49 37q-53 36 -81 57
+q-77 58 -179 211t-185 310zM549 177q-76 60 -132.5 125t-98 143.5t-71 154.5t-58.5 186t-52 209t-60.5 252t-76.5 289q273 0 497.5 -36t379 -92t271 -144.5t185.5 -172.5t110 -198.5t56 -199.5t12.5 -198.5t-9.5 -173t-20 -143.5t-13 -107l323 -327h-104l-281 285
+q-22 -2 -91.5 -14t-121.5 -19t-138 -6t-160.5 17t-167.5 59t-179 111z" />
+    <glyph glyph-name="_625" unicode="&#xf29a;" horiz-adv-x="1792" 
+d="M1374 879q-6 26 -28.5 39.5t-48.5 7.5q-261 -62 -401 -62t-401 62q-26 6 -48.5 -7.5t-28.5 -39.5t7.5 -48.5t39.5 -28.5q194 -46 303 -58q-2 -158 -15.5 -269t-26.5 -155.5t-41 -115.5l-9 -21q-10 -25 1 -49t36 -34q9 -4 23 -4q44 0 60 41l8 20q54 139 71 259h42
+q17 -120 71 -259l8 -20q16 -41 60 -41q14 0 23 4q25 10 36 34t1 49l-9 21q-28 71 -41 115.5t-26.5 155.5t-15.5 269q109 12 303 58q26 6 39.5 28.5t7.5 48.5zM1024 1024q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z
+M1600 640q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5zM896 1408q-156 0 -298 -61t-245 -164t-164 -245t-61 -298t61 -298
+t164 -245t245 -164t298 -61t298 61t245 164t164 245t61 298t-61 298t-164 245t-245 164t-298 61zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="_626" unicode="&#xf29b;" 
+d="M1438 723q34 -35 29 -82l-44 -551q-4 -42 -34.5 -70t-71.5 -28q-6 0 -9 1q-44 3 -72.5 36.5t-25.5 77.5l35 429l-143 -8q55 -113 55 -240q0 -216 -148 -372l-137 137q91 101 91 235q0 145 -102.5 248t-247.5 103q-134 0 -236 -92l-137 138q120 114 284 141l264 300
+l-149 87l-181 -161q-33 -30 -77 -27.5t-73 35.5t-26.5 77t34.5 73l239 213q26 23 60 26.5t64 -14.5l488 -283q36 -21 48 -68q17 -67 -26 -117l-205 -232l371 20q49 3 83 -32zM1240 1180q-74 0 -126 52t-52 126t52 126t126 52t126.5 -52t52.5 -126t-52.5 -126t-126.5 -52z
+M613 -62q106 0 196 61l139 -139q-146 -116 -335 -116q-148 0 -273.5 73t-198.5 198t-73 273q0 188 116 336l139 -139q-60 -88 -60 -197q0 -145 102.5 -247.5t247.5 -102.5z" />
+    <glyph glyph-name="_627" unicode="&#xf29c;" 
+d="M880 336v-160q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h160q14 0 23 -9t9 -23zM1136 832q0 -50 -15 -90t-45.5 -69t-52 -44t-59.5 -36q-32 -18 -46.5 -28t-26 -24t-11.5 -29v-32q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v68q0 35 10.5 64.5
+t24 47.5t39 35.5t41 25.5t44.5 21q53 25 75 43t22 49q0 42 -43.5 71.5t-95.5 29.5q-56 0 -95 -27q-29 -20 -80 -83q-9 -12 -25 -12q-11 0 -19 6l-108 82q-10 7 -12 20t5 23q122 192 349 192q129 0 238.5 -89.5t109.5 -214.5zM768 1280q-130 0 -248.5 -51t-204 -136.5
+t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5
+t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="_628" unicode="&#xf29d;" horiz-adv-x="1408" 
+d="M366 1225q-64 0 -110 45.5t-46 110.5q0 64 46 109.5t110 45.5t109.5 -45.5t45.5 -109.5q0 -65 -45.5 -110.5t-109.5 -45.5zM917 583q0 -50 -30 -67.5t-63.5 -6.5t-47.5 34l-367 438q-7 12 -14 15.5t-11 1.5l-3 -3q-7 -8 4 -21l122 -139l1 -354l-161 -457
+q-67 -192 -92 -234q-15 -26 -28 -32q-50 -26 -103 -1q-29 13 -41.5 43t-9.5 57q2 17 197 618l5 416l-85 -164l35 -222q4 -24 -1 -42t-14 -27.5t-19 -16t-17 -7.5l-7 -2q-19 -3 -34.5 3t-24 16t-14 22t-7.5 19.5t-2 9.5l-46 299l211 381q23 34 113 34q75 0 107 -40l424 -521
+q7 -5 14 -17l3 -3l-1 -1q7 -13 7 -29zM514 433q43 -113 88.5 -225t69.5 -168l24 -55q36 -93 42 -125q11 -70 -36 -97q-35 -22 -66 -16t-51 22t-29 35h-1q-6 16 -8 25l-124 351zM1338 -159q31 -49 31 -57q0 -5 -3 -7q-9 -5 -14.5 0.5t-15.5 26t-16 30.5q-114 172 -423 661
+q3 -1 7 1t7 4l3 2q11 9 11 17z" />
+    <glyph glyph-name="_629" unicode="&#xf29e;" horiz-adv-x="2304" 
+d="M504 542h171l-1 265zM1530 641q0 87 -50.5 140t-146.5 53h-54v-388h52q91 0 145 57t54 138zM956 1018l1 -756q0 -14 -9.5 -24t-23.5 -10h-216q-14 0 -23.5 10t-9.5 24v62h-291l-55 -81q-10 -15 -28 -15h-267q-21 0 -30.5 18t3.5 35l556 757q9 14 27 14h332q14 0 24 -10
+t10 -24zM1783 641q0 -193 -125.5 -303t-324.5 -110h-270q-14 0 -24 10t-10 24v756q0 14 10 24t24 10h268q200 0 326 -109t126 -302zM1939 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5
+t-7.5 60t-20 91.5t-41 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2123 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-45 -108t-74 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5
+h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2304 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66 104.5t41 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96
+t9.5 -70.5z" />
+    <glyph glyph-name="uniF2A0" unicode="&#xf2a0;" horiz-adv-x="1408" 
+d="M617 -153q0 11 -13 58t-31 107t-20 69q-1 4 -5 26.5t-8.5 36t-13.5 21.5q-15 14 -51 14q-23 0 -70 -5.5t-71 -5.5q-34 0 -47 11q-6 5 -11 15.5t-7.5 20t-6.5 24t-5 18.5q-37 128 -37 255t37 255q1 4 5 18.5t6.5 24t7.5 20t11 15.5q13 11 47 11q24 0 71 -5.5t70 -5.5
+q36 0 51 14q9 8 13.5 21.5t8.5 36t5 26.5q2 9 20 69t31 107t13 58q0 22 -43.5 52.5t-75.5 42.5q-20 8 -45 8q-34 0 -98 -18q-57 -17 -96.5 -40.5t-71 -66t-46 -70t-45.5 -94.5q-6 -12 -9 -19q-49 -107 -68 -216t-19 -244t19 -244t68 -216q56 -122 83 -161q63 -91 179 -127
+l6 -2q64 -18 98 -18q25 0 45 8q32 12 75.5 42.5t43.5 52.5zM776 760q-26 0 -45 19t-19 45.5t19 45.5q37 37 37 90q0 52 -37 91q-19 19 -19 45t19 45t45 19t45 -19q75 -75 75 -181t-75 -181q-21 -19 -45 -19zM957 579q-27 0 -45 19q-19 19 -19 45t19 45q112 114 112 272
+t-112 272q-19 19 -19 45t19 45t45 19t45 -19q150 -150 150 -362t-150 -362q-18 -19 -45 -19zM1138 398q-27 0 -45 19q-19 19 -19 45t19 45q90 91 138.5 208t48.5 245t-48.5 245t-138.5 208q-19 19 -19 45t19 45t45 19t45 -19q109 -109 167 -249t58 -294t-58 -294t-167 -249
+q-18 -19 -45 -19z" />
+    <glyph glyph-name="uniF2A1" unicode="&#xf2a1;" horiz-adv-x="2176" 
+d="M192 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 352
+q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 864
+q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 1376q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 192q0 -80 -56 -136
+t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 1216q0 -80 -56 -136t-136 -56
+t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 192q0 -80 -56 -136t-136 -56t-136 56
+t-56 136t56 136t136 56t136 -56t56 -136zM1664 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136
+t56 136t136 56t136 -56t56 -136zM2176 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z" />
+    <glyph glyph-name="uniF2A2" unicode="&#xf2a2;" horiz-adv-x="1792" 
+d="M128 -192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM320 0q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM365 365l256 -256l-90 -90l-256 256zM704 384q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45z
+M1411 704q0 -59 -11.5 -108.5t-37.5 -93.5t-44 -67.5t-53 -64.5q-31 -35 -45.5 -54t-33.5 -50t-26.5 -64t-7.5 -74q0 -159 -112.5 -271.5t-271.5 -112.5q-26 0 -45 19t-19 45t19 45t45 19q106 0 181 75t75 181q0 57 11.5 105.5t37 91t43.5 66.5t52 63q40 46 59.5 72
+t37.5 74.5t18 103.5q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM896 576q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45
+t45 19t45 -19t19 -45zM1184 704q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 93 -65.5 158.5t-158.5 65.5q-92 0 -158 -65.5t-66 -158.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 146 103 249t249 103t249 -103t103 -249zM1578 993q10 -25 -1 -49t-36 -34q-9 -4 -23 -4
+q-19 0 -35.5 11t-23.5 30q-68 178 -224 295q-21 16 -25 42t12 47q17 21 43 25t47 -12q183 -137 266 -351zM1788 1074q9 -25 -1.5 -49t-35.5 -34q-11 -4 -23 -4q-44 0 -60 41q-92 238 -297 393q-22 16 -25.5 42t12.5 47q16 22 42 25.5t47 -12.5q235 -175 341 -449z" />
+    <glyph glyph-name="uniF2A3" unicode="&#xf2a3;" horiz-adv-x="2304" 
+d="M1032 576q-59 2 -84 55q-17 34 -48 53.5t-68 19.5q-53 0 -90.5 -37.5t-37.5 -90.5q0 -56 36 -89l10 -8q34 -31 82 -31q37 0 68 19.5t48 53.5q25 53 84 55zM1600 704q0 56 -36 89l-10 8q-34 31 -82 31q-37 0 -68 -19.5t-48 -53.5q-25 -53 -84 -55q59 -2 84 -55
+q17 -34 48 -53.5t68 -19.5q53 0 90.5 37.5t37.5 90.5zM1174 925q-17 -35 -55 -48t-73 4q-62 31 -134 31q-51 0 -99 -17q3 0 9.5 0.5t9.5 0.5q92 0 170.5 -50t118.5 -133q17 -36 3.5 -73.5t-49.5 -54.5q-18 -9 -39 -9q21 0 39 -9q36 -17 49.5 -54.5t-3.5 -73.5
+q-40 -83 -118.5 -133t-170.5 -50h-6q-16 2 -44 4l-290 27l-239 -120q-14 -7 -29 -7q-40 0 -57 35l-160 320q-11 23 -4 47.5t29 37.5l209 119l148 267q17 155 91.5 291.5t195.5 236.5q31 25 70.5 21.5t64.5 -34.5t21.5 -70t-34.5 -65q-70 -59 -117 -128q123 84 267 101
+q40 5 71.5 -19t35.5 -64q5 -40 -19 -71.5t-64 -35.5q-84 -10 -159 -55q46 10 99 10q115 0 218 -50q36 -18 49 -55.5t-5 -73.5zM2137 1085l160 -320q11 -23 4 -47.5t-29 -37.5l-209 -119l-148 -267q-17 -155 -91.5 -291.5t-195.5 -236.5q-26 -22 -61 -22q-45 0 -74 35
+q-25 31 -21.5 70t34.5 65q70 59 117 128q-123 -84 -267 -101q-4 -1 -12 -1q-36 0 -63.5 24t-31.5 60q-5 40 19 71.5t64 35.5q84 10 159 55q-46 -10 -99 -10q-115 0 -218 50q-36 18 -49 55.5t5 73.5q17 35 55 48t73 -4q62 -31 134 -31q51 0 99 17q-3 0 -9.5 -0.5t-9.5 -0.5
+q-92 0 -170.5 50t-118.5 133q-17 36 -3.5 73.5t49.5 54.5q18 9 39 9q-21 0 -39 9q-36 17 -49.5 54.5t3.5 73.5q40 83 118.5 133t170.5 50h6h1q14 -2 42 -4l291 -27l239 120q14 7 29 7q40 0 57 -35z" />
+    <glyph glyph-name="uniF2A4" unicode="&#xf2a4;" horiz-adv-x="1792" 
+d="M1056 704q0 -26 19 -45t45 -19t45 19t19 45q0 146 -103 249t-249 103t-249 -103t-103 -249q0 -26 19 -45t45 -19t45 19t19 45q0 93 66 158.5t158 65.5t158 -65.5t66 -158.5zM835 1280q-117 0 -223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5q0 -26 19 -45t45 -19t45 19
+t19 45q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -55 -18 -103.5t-37.5 -74.5t-59.5 -72q-34 -39 -52 -63t-43.5 -66.5t-37 -91t-11.5 -105.5q0 -106 -75 -181t-181 -75q-26 0 -45 -19t-19 -45t19 -45t45 -19q159 0 271.5 112.5t112.5 271.5q0 41 7.5 74
+t26.5 64t33.5 50t45.5 54q35 41 53 64.5t44 67.5t37.5 93.5t11.5 108.5q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5zM591 561l226 -226l-579 -579q-12 -12 -29 -12t-29 12l-168 168q-12 12 -12 29t12 29zM1612 1524l168 -168q12 -12 12 -29t-12 -30l-233 -233
+l-26 -25l-71 -71q-66 153 -195 258l91 91l207 207q13 12 30 12t29 -12z" />
+    <glyph glyph-name="uniF2A5" unicode="&#xf2a5;" 
+d="M866 1021q0 -27 -13 -94q-11 -50 -31.5 -150t-30.5 -150q-2 -11 -4.5 -12.5t-13.5 -2.5q-20 -2 -31 -2q-58 0 -84 49.5t-26 113.5q0 88 35 174t103 124q28 14 51 14q28 0 36.5 -16.5t8.5 -47.5zM1352 597q0 14 -39 75.5t-52 66.5q-21 8 -34 8q-91 0 -226 -77l-2 2
+q3 22 27.5 135t24.5 178q0 233 -242 233q-24 0 -68 -6q-94 -17 -168.5 -89.5t-111.5 -166.5t-37 -189q0 -146 80.5 -225t227.5 -79q25 0 25 -3t-1 -5q-4 -34 -26 -117q-14 -52 -51.5 -101t-82.5 -49q-42 0 -42 47q0 24 10.5 47.5t25 39.5t29.5 28.5t26 20t11 8.5q0 3 -7 10
+q-24 22 -58.5 36.5t-65.5 14.5q-35 0 -63.5 -34t-41 -75t-12.5 -75q0 -88 51.5 -142t138.5 -54q82 0 155 53t117.5 126t65.5 153q6 22 15.5 66.5t14.5 66.5q3 12 14 18q118 60 227 60q48 0 127 -18q1 -1 4 -1q5 0 9.5 4.5t4.5 8.5zM1536 1120v-960q0 -119 -84.5 -203.5
+t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="uniF2A6" unicode="&#xf2a6;" horiz-adv-x="1535" 
+d="M744 1231q0 24 -2 38.5t-8.5 30t-21 23t-37.5 7.5q-39 0 -78 -23q-105 -58 -159 -190.5t-54 -269.5q0 -44 8.5 -85.5t26.5 -80.5t52.5 -62.5t81.5 -23.5q4 0 18 -0.5t20 0t16 3t15 8.5t7 16q16 77 48 231.5t48 231.5q19 91 19 146zM1498 575q0 -7 -7.5 -13.5t-15.5 -6.5
+l-6 1q-22 3 -62 11t-72 12.5t-63 4.5q-167 0 -351 -93q-15 -8 -21 -27q-10 -36 -24.5 -105.5t-22.5 -100.5q-23 -91 -70 -179.5t-112.5 -164.5t-154.5 -123t-185 -47q-135 0 -214.5 83.5t-79.5 219.5q0 53 19.5 117t63 116.5t97.5 52.5q38 0 120 -33.5t83 -61.5
+q0 -1 -16.5 -12.5t-39.5 -31t-46 -44.5t-39 -61t-16 -74q0 -33 16.5 -53t48.5 -20q45 0 85 31.5t66.5 78t48 105.5t32.5 107t16 90v9q0 2 -3.5 3.5t-8.5 1.5h-10t-10 -0.5t-6 -0.5q-227 0 -352 122.5t-125 348.5q0 108 34.5 221t96 210t156 167.5t204.5 89.5q52 9 106 9
+q374 0 374 -360q0 -98 -38 -273t-43 -211l3 -3q101 57 182.5 88t167.5 31q22 0 53 -13q19 -7 80 -102.5t61 -116.5z" />
+    <glyph glyph-name="uniF2A7" unicode="&#xf2a7;" horiz-adv-x="1664" 
+d="M831 863q32 0 59 -18l222 -148q61 -40 110 -97l146 -170q40 -46 29 -106l-72 -413q-6 -32 -29.5 -53.5t-55.5 -25.5l-527 -56l-352 -32h-9q-39 0 -67.5 28t-28.5 68q0 37 27 64t65 32l260 32h-448q-41 0 -69.5 30t-26.5 71q2 39 32 65t69 26l442 1l-521 64q-41 5 -66 37
+t-19 73q6 35 34.5 57.5t65.5 22.5h10l481 -60l-351 94q-38 10 -62 41.5t-18 68.5q6 36 33 58.5t62 22.5q6 0 20 -2l448 -96l217 -37q1 0 3 -0.5t3 -0.5q23 0 30.5 23t-12.5 36l-186 125q-35 23 -42 63.5t18 73.5q27 38 76 38zM761 661l186 -125l-218 37l-5 2l-36 38
+l-238 262q-1 1 -2.5 3.5t-2.5 3.5q-24 31 -18.5 70t37.5 64q31 23 68 17.5t64 -33.5l142 -147q-2 -1 -5 -3.5t-4 -4.5q-32 -45 -23 -99t55 -85zM1648 1115l15 -266q4 -73 -11 -147l-48 -219q-12 -59 -67 -87l-106 -54q2 62 -39 109l-146 170q-53 61 -117 103l-222 148
+q-34 23 -76 23q-51 0 -88 -37l-235 312q-25 33 -18 73.5t41 63.5q33 22 71.5 14t62.5 -40l266 -352l-262 455q-21 35 -10.5 75t47.5 59q35 18 72.5 6t57.5 -46l241 -420l-136 337q-15 35 -4.5 74t44.5 56q37 19 76 6t56 -51l193 -415l101 -196q8 -15 23 -17.5t27 7.5t11 26
+l-12 224q-2 41 26 71t69 31q39 0 67 -28.5t30 -67.5z" />
+    <glyph glyph-name="uniF2A8" unicode="&#xf2a8;" horiz-adv-x="1792" 
+d="M335 180q-2 0 -6 2q-86 57 -168.5 145t-139.5 180q-21 30 -21 69q0 9 2 19t4 18t7 18t8.5 16t10.5 17t10 15t12 15.5t11 14.5q184 251 452 365q-110 198 -110 211q0 19 17 29q116 64 128 64q18 0 28 -16l124 -229q92 19 192 19q266 0 497.5 -137.5t378.5 -369.5
+q20 -31 20 -69t-20 -69q-91 -142 -218.5 -253.5t-278.5 -175.5q110 -198 110 -211q0 -20 -17 -29q-116 -64 -127 -64q-19 0 -29 16l-124 229l-64 119l-444 820l7 7q-58 -24 -99 -47q3 -5 127 -234t243 -449t119 -223q0 -7 -9 -9q-13 -3 -72 -3q-57 0 -60 7l-456 841
+q-39 -28 -82 -68q24 -43 214 -393.5t190 -354.5q0 -10 -11 -10q-14 0 -82.5 22t-72.5 28l-106 197l-224 413q-44 -53 -78 -106q2 -3 18 -25t23 -34l176 -327q0 -10 -10 -10zM1165 282l49 -91q273 111 450 385q-180 277 -459 389q67 -64 103 -148.5t36 -176.5
+q0 -106 -47 -200.5t-132 -157.5zM848 896q0 -20 14 -34t34 -14q86 0 147 -61t61 -147q0 -20 14 -34t34 -14t34 14t14 34q0 126 -89 215t-215 89q-20 0 -34 -14t-14 -34zM1214 961l-9 4l7 -7z" />
+    <glyph glyph-name="uniF2A9" unicode="&#xf2a9;" horiz-adv-x="1280" 
+d="M1050 430q0 -215 -147 -374q-148 -161 -378 -161q-232 0 -378 161q-147 159 -147 374q0 147 68 270.5t189 196.5t268 73q96 0 182 -31q-32 -62 -39 -126q-66 28 -143 28q-167 0 -280.5 -123t-113.5 -291q0 -170 112.5 -288.5t281.5 -118.5t281 118.5t112 288.5
+q0 89 -32 166q66 13 123 49q41 -98 41 -212zM846 619q0 -192 -79.5 -345t-238.5 -253l-14 -1q-29 0 -62 5q83 32 146.5 102.5t99.5 154.5t58.5 189t30 192.5t7.5 178.5q0 69 -3 103q55 -160 55 -326zM791 947v-2q-73 214 -206 440q88 -59 142.5 -186.5t63.5 -251.5z
+M1035 744q-83 0 -160 75q218 120 290 247q19 37 21 56q-42 -94 -139.5 -166.5t-204.5 -97.5q-35 54 -35 113q0 37 17 79t43 68q46 44 157 74q59 16 106 58.5t74 100.5q74 -105 74 -253q0 -109 -24 -170q-32 -77 -88.5 -130.5t-130.5 -53.5z" />
+    <glyph glyph-name="uniF2AA" unicode="&#xf2aa;" 
+d="M1050 495q0 78 -28 147q-41 -25 -85 -34q22 -50 22 -114q0 -117 -77 -198.5t-193 -81.5t-193.5 81.5t-77.5 198.5q0 115 78 199.5t193 84.5q53 0 98 -19q4 43 27 87q-60 21 -125 21q-154 0 -257.5 -108.5t-103.5 -263.5t103.5 -261t257.5 -106t257.5 106.5t103.5 260.5z
+M872 850q2 -24 2 -71q0 -63 -5 -123t-20.5 -132.5t-40.5 -130t-68.5 -106t-100.5 -70.5q21 -3 42 -3h10q219 139 219 411q0 116 -38 225zM872 850q-4 80 -44 171.5t-98 130.5q92 -156 142 -302zM1207 955q0 102 -51 174q-41 -86 -124 -109q-69 -19 -109 -53.5t-40 -99.5
+q0 -40 24 -77q74 17 140.5 67t95.5 115q-4 -52 -74.5 -111.5t-138.5 -97.5q52 -52 110 -52q51 0 90 37t60 90q17 42 17 117zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
+t84.5 -203.5z" />
+    <glyph glyph-name="uniF2AB" unicode="&#xf2ab;" 
+d="M1279 388q0 22 -22 27q-67 15 -118 59t-80 108q-7 19 -7 25q0 15 19.5 26t43 17t43 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-12 0 -32 -8t-31 -8q-4 0 -12 2q5 95 5 114q0 79 -17 114q-36 78 -103 121.5t-152 43.5q-199 0 -275 -165q-17 -35 -17 -114q0 -19 5 -114
+q-4 -2 -14 -2q-12 0 -32 7.5t-30 7.5q-21 0 -38.5 -12t-17.5 -32q0 -21 19.5 -35.5t43 -20.5t43 -17t19.5 -26q0 -6 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -46 137 -68q2 -5 6 -26t11.5 -30.5t23.5 -9.5q12 0 37.5 4.5t39.5 4.5q35 0 67 -15t54 -32.5t57.5 -32.5
+t76.5 -15q43 0 79 15t57.5 32.5t53.5 32.5t67 15q14 0 39.5 -4t38.5 -4q16 0 23 10t11 30t6 25q137 22 137 68zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
+t103 -385.5z" />
+    <glyph glyph-name="uniF2AC" unicode="&#xf2ac;" horiz-adv-x="1664" 
+d="M848 1408q134 1 240.5 -68.5t163.5 -192.5q27 -58 27 -179q0 -47 -9 -191q14 -7 28 -7q18 0 51 13.5t51 13.5q29 0 56 -18t27 -46q0 -32 -31.5 -54t-69 -31.5t-69 -29t-31.5 -47.5q0 -15 12 -43q37 -82 102.5 -150t144.5 -101q28 -12 80 -23q28 -6 28 -35
+q0 -70 -219 -103q-7 -11 -11 -39t-14 -46.5t-33 -18.5q-20 0 -62 6.5t-64 6.5q-37 0 -62 -5q-32 -5 -63 -22.5t-58 -38t-58 -40.5t-76 -33.5t-99 -13.5q-52 0 -96.5 13.5t-75 33.5t-57.5 40.5t-58 38t-62 22.5q-26 5 -63 5q-24 0 -65.5 -7.5t-58.5 -7.5q-25 0 -35 18.5
+t-14 47.5t-11 40q-219 33 -219 103q0 29 28 35q52 11 80 23q78 32 144.5 101t102.5 150q12 28 12 43q0 28 -31.5 47.5t-69.5 29.5t-69.5 31.5t-31.5 52.5q0 27 26 45.5t55 18.5q15 0 48 -13t53 -13q18 0 32 7q-9 142 -9 190q0 122 27 180q64 137 172 198t264 63z" />
+    <glyph glyph-name="uniF2AD" unicode="&#xf2ad;" 
+d="M1280 388q0 22 -22 27q-67 14 -118 58t-80 109q-7 14 -7 25q0 15 19.5 26t42.5 17t42.5 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-11 0 -31 -8t-32 -8q-4 0 -12 2q5 63 5 115q0 78 -17 114q-36 78 -102.5 121.5t-152.5 43.5q-198 0 -275 -165q-18 -38 -18 -115
+q0 -38 6 -114q-10 -2 -15 -2q-11 0 -31.5 8t-30.5 8q-20 0 -37.5 -12.5t-17.5 -32.5q0 -21 19.5 -35.5t42.5 -20.5t42.5 -17t19.5 -26q0 -11 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -47 138 -69q2 -5 6 -26t11 -30.5t23 -9.5q13 0 38.5 5t38.5 5q35 0 67.5 -15
+t54.5 -32.5t57.5 -32.5t76.5 -15q43 0 79 15t57.5 32.5t54 32.5t67.5 15q13 0 39 -4.5t39 -4.5q15 0 22.5 9.5t11.5 31t5 24.5q138 22 138 69zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960
+q119 0 203.5 -84.5t84.5 -203.5z" />
+    <glyph glyph-name="uniF2AE" unicode="&#xf2ae;" horiz-adv-x="2304" 
+d="M2304 1536q-69 -46 -125 -92t-89 -81t-59.5 -71.5t-37.5 -57.5t-22 -44.5t-14 -29.5q-10 -18 -35.5 -136.5t-48.5 -164.5q-15 -29 -50 -60.5t-67.5 -50.5t-72.5 -41t-48 -28q-47 -31 -151 -231q-341 14 -630 -158q-92 -53 -303 -179q47 16 86 31t55 22l15 7
+q71 27 163 64.5t133.5 53.5t108 34.5t142.5 31.5q186 31 465 -7q1 0 10 -3q11 -6 14 -17t-3 -22l-194 -345q-15 -29 -47 -22q-128 24 -354 24q-146 0 -402 -44.5t-392 -46.5q-82 -1 -149 13t-107 37t-61 40t-33 34l-1 1v2q0 6 6 6q138 0 371 55q192 366 374.5 524t383.5 158
+q5 0 14.5 -0.5t38 -5t55 -12t61.5 -24.5t63 -39.5t54 -59t40 -82.5l102 177q2 4 21 42.5t44.5 86.5t61 109.5t84 133.5t100.5 137q66 82 128 141.5t121.5 96.5t92.5 53.5t88 39.5z" />
+    <glyph glyph-name="uniF2B0" unicode="&#xf2b0;" 
+d="M1322 640q0 -45 -5 -76l-236 14l224 -78q-19 -73 -58 -141l-214 103l177 -158q-44 -61 -107 -108l-157 178l103 -215q-61 -37 -140 -59l-79 228l14 -240q-38 -6 -76 -6t-76 6l14 238l-78 -226q-74 19 -140 59l103 215l-157 -178q-59 43 -108 108l178 158l-214 -104
+q-39 69 -58 141l224 79l-237 -14q-5 42 -5 76q0 35 5 77l238 -14l-225 79q19 73 58 140l214 -104l-177 159q46 61 107 108l158 -178l-103 215q67 39 140 58l77 -224l-13 236q36 6 75 6q38 0 76 -6l-14 -237l78 225q74 -19 140 -59l-103 -214l158 178q61 -47 107 -108
+l-177 -159l213 104q37 -62 58 -141l-224 -78l237 14q5 -31 5 -77zM1352 640q0 160 -78.5 295.5t-213 214t-292.5 78.5q-119 0 -227 -46.5t-186.5 -125t-124.5 -187.5t-46 -229q0 -119 46 -228t124.5 -187.5t186.5 -125t227 -46.5q158 0 292.5 78.5t213 214t78.5 294.5z
+M1425 1023v-766l-657 -383l-657 383v766l657 383zM768 -183l708 412v823l-708 411l-708 -411v-823zM1536 1088v-896l-768 -448l-768 448v896l768 448z" />
+    <glyph glyph-name="uniF2B1" unicode="&#xf2b1;" horiz-adv-x="1664" 
+d="M339 1318h691l-26 -72h-665q-110 0 -188.5 -79t-78.5 -189v-771q0 -95 60.5 -169.5t153.5 -93.5q23 -5 98 -5v-72h-45q-140 0 -239.5 100t-99.5 240v771q0 140 99.5 240t239.5 100zM1190 1536h247l-482 -1294q-23 -61 -40.5 -103.5t-45 -98t-54 -93.5t-64.5 -78.5
+t-79.5 -65t-95.5 -41t-116 -18.5v195q163 26 220 182q20 52 20 105q0 54 -20 106l-285 733h228l187 -585zM1664 978v-1111h-795q37 55 45 73h678v1038q0 85 -49.5 155t-129.5 99l25 67q101 -34 163.5 -123.5t62.5 -197.5z" />
+    <glyph glyph-name="uniF2B2" unicode="&#xf2b2;" horiz-adv-x="1792" 
+d="M852 1227q0 -29 -17 -52.5t-45 -23.5t-45 23.5t-17 52.5t17 52.5t45 23.5t45 -23.5t17 -52.5zM688 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50 -21.5t-20 -51.5v-114q0 -30 20.5 -52t49.5 -22q30 0 50.5 22t20.5 52zM860 -149v114q0 30 -20 51.5t-50 21.5t-50.5 -21.5
+t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22q29 0 49.5 22t20.5 52zM1034 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1208 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114
+q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1476 535q-84 -160 -232 -259.5t-323 -99.5q-123 0 -229.5 51.5t-178.5 137t-113 197.5t-41 232q0 88 21 174q-104 -175 -104 -390q0 -162 65 -312t185 -251q30 57 91 57q56 0 86 -50q32 50 87 50q56 0 86 -50q32 50 87 50t87 -50
+q30 50 86 50q28 0 52.5 -15.5t37.5 -40.5q112 94 177 231.5t73 287.5zM1326 564q0 75 -72 75q-17 0 -47 -6q-95 -19 -149 -19q-226 0 -226 243q0 86 30 204q-83 -127 -83 -275q0 -150 89 -260.5t235 -110.5q111 0 210 70q13 48 13 79zM884 1223q0 50 -32 89.5t-81 39.5
+t-81 -39.5t-32 -89.5q0 -51 31.5 -90.5t81.5 -39.5t81.5 39.5t31.5 90.5zM1513 884q0 96 -37.5 179t-113 137t-173.5 54q-77 0 -149 -35t-127 -94q-48 -159 -48 -268q0 -104 45.5 -157t147.5 -53q53 0 142 19q36 6 53 6q51 0 77.5 -28t26.5 -80q0 -26 -4 -46
+q75 68 117.5 165.5t42.5 200.5zM1792 667q0 -111 -33.5 -249.5t-93.5 -204.5q-58 -64 -195 -142.5t-228 -104.5l-4 -1v-114q0 -43 -29.5 -75t-72.5 -32q-56 0 -86 50q-32 -50 -87 -50t-87 50q-30 -50 -86 -50q-55 0 -87 50q-30 -50 -86 -50q-47 0 -75 33.5t-28 81.5
+q-90 -68 -198 -68q-118 0 -211 80q54 1 106 20q-113 31 -182 127q32 -7 71 -7q89 0 164 46q-192 192 -240 306q-24 56 -24 160q0 57 9 125.5t31.5 146.5t55 141t86.5 105t120 42q59 0 81 -52q19 29 42 54q2 3 12 13t13 16q10 15 23 38t25 42t28 39q87 111 211.5 177
+t260.5 66q35 0 62 -4q59 64 146 64q83 0 140 -57q5 -5 5 -12q0 -5 -6 -13.5t-12.5 -16t-16 -17l-10.5 -10.5q17 -6 36 -18t19 -24q0 -6 -16 -25q157 -138 197 -378q25 30 60 30q45 0 100 -49q90 -80 90 -279z" />
+    <glyph glyph-name="uniF2B3" unicode="&#xf2b3;" 
+d="M917 631q0 33 -6 64h-362v-132h217q-12 -76 -74.5 -120.5t-142.5 -44.5q-99 0 -169 71.5t-70 170.5t70 170.5t169 71.5q93 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585h109v110
+h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+    <glyph glyph-name="uniF2B4" unicode="&#xf2b4;" 
+d="M1536 1024v-839q0 -48 -49 -62q-174 -52 -338 -52q-73 0 -215.5 29.5t-227.5 29.5q-164 0 -370 -48v-338h-160v1368q-63 25 -101 81t-38 124q0 91 64 155t155 64t155 -64t64 -155q0 -68 -38 -124t-101 -81v-68q190 44 343 44q99 0 198 -15q14 -2 111.5 -22.5t149.5 -20.5
+q77 0 165 18q11 2 80 21t89 19q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="uniF2B5" unicode="&#xf2b5;" horiz-adv-x="2304" 
+d="M192 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32zM1665 442q-10 13 -38.5 50t-41.5 54t-38 49t-42.5 53t-40.5 47t-45 49l-125 -140q-83 -94 -208.5 -92t-205.5 98q-57 69 -56.5 158t58.5 157l177 206q-22 11 -51 16.5t-47.5 6t-56.5 -0.5t-49 -1q-92 0 -158 -66
+l-158 -158h-155v-544q5 0 21 0.5t22 0t19.5 -2t20.5 -4.5t17.5 -8.5t18.5 -13.5l297 -292q115 -111 227 -111q78 0 125 47q57 -20 112.5 8t72.5 85q74 -6 127 44q20 18 36 45.5t14 50.5q10 -10 43 -10q43 0 77 21t49.5 53t12 71.5t-30.5 73.5zM1824 384h96v512h-93l-157 180
+q-66 76 -169 76h-167q-89 0 -146 -67l-209 -243q-28 -33 -28 -75t27 -75q43 -51 110 -52t111 49l193 218q25 23 53.5 21.5t47 -27t8.5 -56.5q16 -19 56 -63t60 -68q29 -36 82.5 -105.5t64.5 -84.5q52 -66 60 -140zM2112 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32z
+M2304 960v-640q0 -26 -19 -45t-45 -19h-434q-27 -65 -82 -106.5t-125 -51.5q-33 -48 -80.5 -81.5t-102.5 -45.5q-42 -53 -104.5 -81.5t-128.5 -24.5q-60 -34 -126 -39.5t-127.5 14t-117 53.5t-103.5 81l-287 282h-358q-26 0 -45 19t-19 45v672q0 26 19 45t45 19h421
+q14 14 47 48t47.5 48t44 40t50.5 37.5t51 25.5t62 19.5t68 5.5h117q99 0 181 -56q82 56 181 56h167q35 0 67 -6t56.5 -14.5t51.5 -26.5t44.5 -31t43 -39.5t39 -42t41 -48t41.5 -48.5h355q26 0 45 -19t19 -45z" />
+    <glyph glyph-name="uniF2B6" unicode="&#xf2b6;" horiz-adv-x="1792" 
+d="M1792 882v-978q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v978q0 15 11 24q8 7 39 34.5t41.5 36t45.5 37.5t70 55.5t96 73t143.5 107t192.5 140.5q5 4 52.5 40t71.5 52.5t64 35t69 18.5t69 -18.5t65 -35.5t71 -52t52 -40q110 -80 192.5 -140.5t143.5 -107
+t96 -73t70 -55.5t45.5 -37.5t41.5 -36t39 -34.5q11 -9 11 -24zM1228 297q263 191 345 252q11 8 12.5 20.5t-6.5 23.5l-38 52q-8 11 -21 12.5t-24 -6.5q-231 -169 -343 -250q-5 -3 -52 -39t-71.5 -52.5t-64.5 -35t-69 -18.5t-69 18.5t-64.5 35t-71.5 52.5t-52 39
+q-186 134 -343 250q-11 8 -24 6.5t-21 -12.5l-38 -52q-8 -11 -6.5 -23.5t12.5 -20.5q82 -61 345 -252q10 -8 50 -38t65 -47t64 -39.5t77.5 -33.5t75.5 -11t75.5 11t79 34.5t64.5 39.5t65 47.5t48 36.5z" />
+    <glyph glyph-name="uniF2B7" unicode="&#xf2b7;" horiz-adv-x="1792" 
+d="M1474 623l39 -51q8 -11 6.5 -23.5t-11.5 -20.5q-43 -34 -126.5 -98.5t-146.5 -113t-67 -51.5q-39 -32 -60 -48t-60.5 -41t-76.5 -36.5t-74 -11.5h-1h-1q-37 0 -74 11.5t-76 36.5t-61 41.5t-60 47.5q-5 4 -65 50.5t-143.5 111t-122.5 94.5q-11 8 -12.5 20.5t6.5 23.5
+l37 52q8 11 21.5 13t24.5 -7q94 -73 306 -236q5 -4 43.5 -35t60.5 -46.5t56.5 -32.5t58.5 -17h1h1q24 0 58.5 17t56.5 32.5t60.5 46.5t43.5 35q258 198 313 242q11 8 24 6.5t21 -12.5zM1664 -96v928q-90 83 -159 139q-91 74 -389 304q-3 2 -43 35t-61 48t-56 32.5t-59 17.5
+h-1h-1q-24 0 -59 -17.5t-56 -32.5t-61 -48t-43 -35q-215 -166 -315.5 -245.5t-129.5 -104t-82 -74.5q-14 -12 -21 -19v-928q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 832v-928q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v928q0 56 41 94
+q123 114 350 290.5t233 181.5q36 30 59 47.5t61.5 42t76 36.5t74.5 12h1h1q37 0 74.5 -12t76 -36.5t61.5 -42t59 -47.5q43 -36 156 -122t226 -177t201 -173q41 -38 41 -94z" />
+    <glyph glyph-name="uniF2B8" unicode="&#xf2b8;" 
+d="M330 1l202 -214l-34 236l-216 213zM556 -225l274 218l-11 245l-300 -215zM245 413l227 -213l-48 327l-245 204zM495 189l317 214l-14 324l-352 -200zM843 178l95 -80l-2 239l-103 79q0 -1 1 -8.5t0 -12t-5 -7.5l-78 -52l85 -70q7 -6 7 -88zM138 930l256 -200l-68 465
+l-279 173zM1173 267l15 234l-230 -164l2 -240zM417 722l373 194l-19 441l-423 -163zM1270 357l20 233l-226 142l-2 -105l144 -95q6 -4 4 -9l-7 -119zM1461 496l30 222l-179 -128l-20 -228zM1273 329l-71 49l-8 -117q0 -5 -4 -8l-234 -187q-7 -5 -14 0l-98 83l7 -161
+q0 -5 -4 -8l-293 -234q-4 -2 -6 -2q-8 2 -8 3l-228 242q-4 4 -59 277q-2 7 5 11l61 37q-94 86 -95 92l-72 351q-2 7 6 12l94 45q-133 100 -135 108l-96 466q-2 10 7 13l433 135q5 0 8 -1l317 -153q6 -4 6 -9l20 -463q0 -7 -6 -10l-118 -61l126 -85q5 -2 5 -8l5 -123l121 74
+q5 4 11 0l84 -56l3 110q0 6 5 9l206 126q6 3 11 0l245 -135q4 -4 5 -7t-6.5 -60t-17.5 -124.5t-10 -70.5q0 -5 -4 -7l-191 -153q-6 -5 -13 0z" />
+    <glyph glyph-name="uniF2B9" unicode="&#xf2b9;" horiz-adv-x="1664" 
+d="M1201 298q0 57 -5.5 107t-21 100.5t-39.5 86t-64 58t-91 22.5q-6 -4 -33.5 -20.5t-42.5 -24.5t-40.5 -20t-49 -17t-46.5 -5t-46.5 5t-49 17t-40.5 20t-42.5 24.5t-33.5 20.5q-51 0 -91 -22.5t-64 -58t-39.5 -86t-21 -100.5t-5.5 -107q0 -73 42 -121.5t103 -48.5h576
+q61 0 103 48.5t42 121.5zM1028 892q0 108 -76.5 184t-183.5 76t-183.5 -76t-76.5 -184q0 -107 76.5 -183t183.5 -76t183.5 76t76.5 183zM1664 352v-192q0 -14 -9 -23t-23 -9h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216
+q66 0 113 -47t47 -113v-224h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23z" />
+    <glyph glyph-name="uniF2BA" unicode="&#xf2ba;" horiz-adv-x="1664" 
+d="M1028 892q0 -107 -76.5 -183t-183.5 -76t-183.5 76t-76.5 183q0 108 76.5 184t183.5 76t183.5 -76t76.5 -184zM980 672q46 0 82.5 -17t60 -47.5t39.5 -67t24 -81t11.5 -82.5t3.5 -79q0 -67 -39.5 -118.5t-105.5 -51.5h-576q-66 0 -105.5 51.5t-39.5 118.5q0 48 4.5 93.5
+t18.5 98.5t36.5 91.5t63 64.5t93.5 26h5q7 -4 32 -19.5t35.5 -21t33 -17t37 -16t35 -9t39.5 -4.5t39.5 4.5t35 9t37 16t33 17t35.5 21t32 19.5zM1664 928q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96
+q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216q66 0 113 -47t47 -113v-224h96q13 0 22.5 -9.5t9.5 -22.5v-192zM1408 -96v1472q0 13 -9.5 22.5t-22.5 9.5h-1216
+q-13 0 -22.5 -9.5t-9.5 -22.5v-1472q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5z" />
+    <glyph glyph-name="uniF2BB" unicode="&#xf2bb;" horiz-adv-x="2048" 
+d="M1024 405q0 64 -9 117.5t-29.5 103t-60.5 78t-97 28.5q-6 -4 -30 -18t-37.5 -21.5t-35.5 -17.5t-43 -14.5t-42 -4.5t-42 4.5t-43 14.5t-35.5 17.5t-37.5 21.5t-30 18q-57 0 -97 -28.5t-60.5 -78t-29.5 -103t-9 -117.5t37 -106.5t91 -42.5h512q54 0 91 42.5t37 106.5z
+M867 925q0 94 -66.5 160.5t-160.5 66.5t-160.5 -66.5t-66.5 -160.5t66.5 -160.5t160.5 -66.5t160.5 66.5t66.5 160.5zM1792 416v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1792 676v56q0 15 -10.5 25.5t-25.5 10.5h-568
+q-15 0 -25.5 -10.5t-10.5 -25.5v-56q0 -15 10.5 -25.5t25.5 -10.5h568q15 0 25.5 10.5t10.5 25.5zM1792 928v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-352v96q0 14 -9 23t-23 9
+h-64q-14 0 -23 -9t-9 -23v-96h-768v96q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-96h-352q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="uniF2BC" unicode="&#xf2bc;" horiz-adv-x="2048" 
+d="M1024 405q0 -64 -37 -106.5t-91 -42.5h-512q-54 0 -91 42.5t-37 106.5t9 117.5t29.5 103t60.5 78t97 28.5q6 -4 30 -18t37.5 -21.5t35.5 -17.5t43 -14.5t42 -4.5t42 4.5t43 14.5t35.5 17.5t37.5 21.5t30 18q57 0 97 -28.5t60.5 -78t29.5 -103t9 -117.5zM867 925
+q0 -94 -66.5 -160.5t-160.5 -66.5t-160.5 66.5t-66.5 160.5t66.5 160.5t160.5 66.5t160.5 -66.5t66.5 -160.5zM1792 480v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1792 732v-56q0 -15 -10.5 -25.5t-25.5 -10.5h-568
+q-15 0 -25.5 10.5t-10.5 25.5v56q0 15 10.5 25.5t25.5 10.5h568q15 0 25.5 -10.5t10.5 -25.5zM1792 992v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1920 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1728q-13 0 -22.5 -9.5
+t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h352v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h768v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h352q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113
+t113 47h1728q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="uniF2BD" unicode="&#xf2bd;" horiz-adv-x="1792" 
+d="M1523 197q-22 155 -87.5 257.5t-184.5 118.5q-67 -74 -159.5 -115.5t-195.5 -41.5t-195.5 41.5t-159.5 115.5q-119 -16 -184.5 -118.5t-87.5 -257.5q106 -150 271 -237.5t356 -87.5t356 87.5t271 237.5zM1280 896q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5
+t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1792 640q0 -182 -71 -347.5t-190.5 -286t-285.5 -191.5t-349 -71q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="uniF2BE" unicode="&#xf2be;" horiz-adv-x="1792" 
+d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348q0 -181 -70.5 -347t-190.5 -286t-286 -191.5t-349 -71.5t-349 71t-285.5 191.5t-190.5 286t-71 347.5t71 348t191 286t286 191t348 71zM1515 185q149 205 149 455q0 156 -61 298t-164 245t-245 164t-298 61t-298 -61
+t-245 -164t-164 -245t-61 -298q0 -250 149 -455q66 327 306 327q131 -128 313 -128t313 128q240 0 306 -327zM1280 832q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5z" />
+    <glyph glyph-name="uniF2C0" unicode="&#xf2c0;" 
+d="M1201 752q47 -14 89.5 -38t89 -73t79.5 -115.5t55 -172t22 -236.5q0 -154 -100 -263.5t-241 -109.5h-854q-141 0 -241 109.5t-100 263.5q0 131 22 236.5t55 172t79.5 115.5t89 73t89.5 38q-79 125 -79 272q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5
+t198.5 -40.5t163.5 -109.5t109.5 -163.5t40.5 -198.5q0 -147 -79 -272zM768 1408q-159 0 -271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5zM1195 -128q88 0 150.5 71.5t62.5 173.5q0 239 -78.5 377t-225.5 145
+q-145 -127 -336 -127t-336 127q-147 -7 -225.5 -145t-78.5 -377q0 -102 62.5 -173.5t150.5 -71.5h854z" />
+    <glyph glyph-name="uniF2C1" unicode="&#xf2c1;" horiz-adv-x="1280" 
+d="M1024 278q0 -64 -37 -107t-91 -43h-512q-54 0 -91 43t-37 107t9 118t29.5 104t61 78.5t96.5 28.5q80 -75 188 -75t188 75q56 0 96.5 -28.5t61 -78.5t29.5 -104t9 -118zM870 797q0 -94 -67.5 -160.5t-162.5 -66.5t-162.5 66.5t-67.5 160.5t67.5 160.5t162.5 66.5
+t162.5 -66.5t67.5 -160.5zM1152 -96v1376h-1024v-1376q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1280 1376v-1472q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h352v-96q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v96h352
+q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="uniF2C2" unicode="&#xf2c2;" horiz-adv-x="2048" 
+d="M896 324q0 54 -7.5 100.5t-24.5 90t-51 68.5t-81 25q-64 -64 -156 -64t-156 64q-47 0 -81 -25t-51 -68.5t-24.5 -90t-7.5 -100.5q0 -55 31.5 -93.5t75.5 -38.5h426q44 0 75.5 38.5t31.5 93.5zM768 768q0 80 -56 136t-136 56t-136 -56t-56 -136t56 -136t136 -56t136 56
+t56 136zM1792 288v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1408 544v64q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1792 544v64q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23
+v-64q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1792 800v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM128 1152h1792v96q0 14 -9 23t-23 9h-1728q-14 0 -23 -9t-9 -23v-96zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728
+q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="uniF2C3" unicode="&#xf2c3;" horiz-adv-x="2048" 
+d="M896 324q0 -55 -31.5 -93.5t-75.5 -38.5h-426q-44 0 -75.5 38.5t-31.5 93.5q0 54 7.5 100.5t24.5 90t51 68.5t81 25q64 -64 156 -64t156 64q47 0 81 -25t51 -68.5t24.5 -90t7.5 -100.5zM768 768q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z
+M1792 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1408 608v-64q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h320q14 0 23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v64
+q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 864v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1920 32v1120h-1792v-1120q0 -13 9.5 -22.5t22.5 -9.5h1728q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47
+h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="uniF2C4" unicode="&#xf2c4;" horiz-adv-x="1792" 
+d="M1255 749q0 318 -105 474.5t-330 156.5q-222 0 -326 -157t-104 -474q0 -316 104 -471.5t326 -155.5q74 0 131 17q-22 43 -39 73t-44 65t-53.5 56.5t-63 36t-77.5 14.5q-46 0 -79 -16l-49 97q105 91 276 91q132 0 215.5 -54t150.5 -155q67 149 67 402zM1645 117h117
+q3 -27 -2 -67t-26.5 -95t-58 -100.5t-107 -78t-162.5 -32.5q-71 0 -130.5 19t-105.5 56t-79 78t-66 96q-97 -27 -205 -27q-150 0 -292.5 58t-253 158.5t-178 249t-67.5 317.5q0 170 67.5 319.5t178.5 250.5t253.5 159t291.5 58q121 0 238.5 -36t217 -106t176 -164.5
+t119.5 -219t43 -261.5q0 -190 -80.5 -347.5t-218.5 -264.5q47 -70 93.5 -106.5t104.5 -36.5q61 0 94 37.5t38 85.5z" />
+    <glyph glyph-name="uniF2C5" unicode="&#xf2c5;" horiz-adv-x="2304" 
+d="M453 -101q0 -21 -16 -37.5t-37 -16.5q-1 0 -13 3q-63 15 -162 140q-225 284 -225 676q0 341 213 614q39 51 95 103.5t94 52.5q19 0 35 -13.5t16 -32.5q0 -27 -63 -90q-98 -102 -147 -184q-119 -199 -119 -449q0 -281 123 -491q50 -85 136 -173q2 -3 14.5 -16t19.5 -21
+t17 -20.5t14.5 -23.5t4.5 -21zM1796 33q0 -29 -17.5 -48.5t-46.5 -19.5h-1081q-26 0 -45 19t-19 45q0 29 17.5 48.5t46.5 19.5h1081q26 0 45 -19t19 -45zM1581 644q0 -134 -67 -233q-25 -38 -69.5 -78.5t-83.5 -60.5q-16 -10 -27 -10q-7 0 -15 6t-8 12q0 9 19 30t42 46
+t42 67.5t19 88.5q0 76 -35 130q-29 42 -46 42q-3 0 -3 -5q0 -12 7.5 -35.5t7.5 -36.5q0 -22 -21.5 -35t-44.5 -13q-66 0 -66 76q0 15 1.5 44t1.5 44q0 25 -10 46q-13 25 -42 53.5t-51 28.5q-5 0 -7 -0.5t-3.5 -2.5t-1.5 -6q0 -2 16 -26t16 -54q0 -37 -19 -68t-46 -54
+t-53.5 -46t-45.5 -54t-19 -68q0 -98 42 -160q29 -43 79 -63q16 -5 17 -10q1 -2 1 -5q0 -16 -18 -16q-6 0 -33 11q-119 43 -195 139.5t-76 218.5q0 55 24.5 115.5t60 115t70.5 108.5t59.5 113.5t24.5 111.5q0 53 -25 94q-29 48 -56 64q-19 9 -19 21q0 20 41 20q50 0 110 -29
+q41 -19 71 -44.5t49.5 -51t33.5 -62.5t22 -69t16 -80q0 -1 3 -17.5t4.5 -25t5.5 -25t9 -27t11 -21.5t14.5 -16.5t18.5 -5.5q23 0 37 14t14 37q0 25 -20 67t-20 52t10 10q27 0 93 -70q72 -76 102.5 -156t30.5 -186zM2304 615q0 -274 -138 -503q-19 -32 -48 -72t-68 -86.5
+t-81 -77t-74 -30.5q-16 0 -31 15.5t-15 31.5q0 15 29 50.5t68.5 77t48.5 52.5q183 230 183 531q0 131 -20.5 235t-72.5 211q-58 119 -163 228q-2 3 -13 13.5t-16.5 16.5t-15 17.5t-15 20t-9.5 18.5t-4 19q0 19 16 35.5t35 16.5q70 0 196 -169q98 -131 146 -273t60 -314
+q2 -42 2 -64z" />
+    <glyph glyph-name="uniF2C6" unicode="&#xf2c6;" horiz-adv-x="1792" 
+d="M1189 229l147 693q9 44 -10.5 63t-51.5 7l-864 -333q-29 -11 -39.5 -25t-2.5 -26.5t32 -19.5l221 -69l513 323q21 14 32 6q7 -5 -4 -15l-415 -375v0v0l-16 -228q23 0 45 22l108 104l224 -165q64 -36 81 38zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71
+t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="uniF2C7" unicode="&#xf2c7;" horiz-adv-x="1024" 
+d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v907h128v-907q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
+t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
+v128h192z" />
+    <glyph glyph-name="uniF2C8" unicode="&#xf2c8;" horiz-adv-x="1024" 
+d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v651h128v-651q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
+t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
+v128h192z" />
+    <glyph glyph-name="uniF2C9" unicode="&#xf2c9;" horiz-adv-x="1024" 
+d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v395h128v-395q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
+t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
+v128h192z" />
+    <glyph glyph-name="uniF2CA" unicode="&#xf2ca;" horiz-adv-x="1024" 
+d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v139h128v-139q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
+t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
+v128h192z" />
+    <glyph glyph-name="uniF2CB" unicode="&#xf2cb;" horiz-adv-x="1024" 
+d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 79 56 135.5t136 56.5t136 -56.5t56 -135.5zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5t93.5 226.5z
+M896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z" />
+    <glyph glyph-name="uniF2CC" unicode="&#xf2cc;" horiz-adv-x="1920" 
+d="M1433 1287q10 -10 10 -23t-10 -23l-626 -626q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l44 44q-72 91 -81.5 207t46.5 215q-74 71 -176 71q-106 0 -181 -75t-75 -181v-1280h-256v1280q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5q106 0 201 -41
+t166 -115q94 39 197 24.5t185 -79.5l44 44q10 10 23 10t23 -10zM1344 1024q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1600 896q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1856 1024q26 0 45 -19t19 -45t-19 -45t-45 -19
+t-45 19t-19 45t19 45t45 19zM1216 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1408 832q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1728 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 768
+q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 640q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1600 768q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 512q-26 0 -45 19t-19 45t19 45t45 19t45 -19
+t19 -45t-19 -45t-45 -19zM1472 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 384
+q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 256q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19z" />
+    <glyph glyph-name="uniF2CD" unicode="&#xf2cd;" horiz-adv-x="1792" 
+d="M1664 448v-192q0 -169 -128 -286v-194q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v118q-63 -22 -128 -22h-768q-65 0 -128 22v-110q0 -17 -9.5 -28.5t-22.5 -11.5h-64q-13 0 -22.5 11.5t-9.5 28.5v186q-128 117 -128 286v192h1536zM704 864q0 -14 -9 -23t-23 -9t-23 9
+t-9 23t9 23t23 9t23 -9t9 -23zM768 928q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM704 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1056q0 -14 -9 -23t-23 -9t-23 9
+t-9 23t9 23t23 9t23 -9t9 -23zM704 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v640q0 106 75 181t181 75q108 0 184 -78q46 19 98 12t93 -39l22 22q11 11 22 0l42 -42
+q11 -11 0 -22l-314 -314q-11 -11 -22 0l-42 42q-11 11 0 22l22 22q-36 46 -40.5 104t23.5 108q-37 35 -88 35q-53 0 -90.5 -37.5t-37.5 -90.5v-640h1504q14 0 23 -9t9 -23zM896 1056q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1120q0 -14 -9 -23t-23 -9
+t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM896 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1248q0 -14 -9 -23
+t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1024 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1088 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23z" />
+    <glyph glyph-name="uniF2CE" unicode="&#xf2ce;" 
+d="M994 344q0 -86 -17 -197q-31 -215 -55 -313q-22 -90 -152 -90t-152 90q-24 98 -55 313q-17 110 -17 197q0 168 224 168t224 -168zM1536 768q0 -240 -134 -434t-350 -280q-8 -3 -15 3t-6 15q7 48 10 66q4 32 6 47q1 9 9 12q159 81 255.5 234t96.5 337q0 180 -91 330.5
+t-247 234.5t-337 74q-124 -7 -237 -61t-193.5 -140.5t-128 -202t-46.5 -240.5q1 -184 99 -336.5t257 -231.5q7 -3 9 -12q3 -21 6 -45q1 -9 5 -32.5t6 -35.5q1 -9 -6.5 -15t-15.5 -2q-148 58 -261 169.5t-173.5 264t-52.5 319.5q7 143 66 273.5t154.5 227t225 157.5t272.5 70
+q164 10 315.5 -46.5t261 -160.5t175 -250.5t65.5 -308.5zM994 800q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5zM1282 768q0 -122 -53.5 -228.5t-146.5 -177.5q-8 -6 -16 -2t-10 14q-6 52 -29 92q-7 10 3 20
+q58 54 91 127t33 155q0 111 -58.5 204t-157.5 141.5t-212 36.5q-133 -15 -229 -113t-109 -231q-10 -92 23.5 -176t98.5 -144q10 -10 3 -20q-24 -41 -29 -93q-2 -9 -10 -13t-16 2q-95 74 -148.5 183t-51.5 234q3 131 69 244t177 181.5t241 74.5q144 7 268 -60t196.5 -187.5
+t72.5 -263.5z" />
+    <glyph glyph-name="uniF2D0" unicode="&#xf2d0;" horiz-adv-x="1792" 
+d="M256 128h1280v768h-1280v-768zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="uniF2D1" unicode="&#xf2d1;" horiz-adv-x="1792" 
+d="M1792 224v-192q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="uniF2D2" unicode="&#xf2d2;" horiz-adv-x="2048" 
+d="M256 0h768v512h-768v-512zM1280 512h512v768h-768v-256h96q66 0 113 -47t47 -113v-352zM2048 1376v-960q0 -66 -47 -113t-113 -47h-608v-352q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h608v352q0 66 47 113t113 47h960q66 0 113 -47
+t47 -113z" />
+    <glyph glyph-name="uniF2D3" unicode="&#xf2d3;" horiz-adv-x="1792" 
+d="M1175 215l146 146q10 10 10 23t-10 23l-233 233l233 233q10 10 10 23t-10 23l-146 146q-10 10 -23 10t-23 -10l-233 -233l-233 233q-10 10 -23 10t-23 -10l-146 -146q-10 -10 -10 -23t10 -23l233 -233l-233 -233q-10 -10 -10 -23t10 -23l146 -146q10 -10 23 -10t23 10
+l233 233l233 -233q10 -10 23 -10t23 10zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="uniF2D4" unicode="&#xf2d4;" horiz-adv-x="1792" 
+d="M1257 425l-146 -146q-10 -10 -23 -10t-23 10l-169 169l-169 -169q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l169 169l-169 169q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l169 -169l169 169q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23
+l-169 -169l169 -169q10 -10 10 -23t-10 -23zM256 128h1280v1024h-1280v-1024zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="uniF2D5" unicode="&#xf2d5;" horiz-adv-x="1792" 
+d="M1070 358l306 564h-654l-306 -564h654zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="uniF2D6" unicode="&#xf2d6;" horiz-adv-x="1794" 
+d="M1291 1060q-15 17 -35 8.5t-26 -28.5t5 -38q14 -17 40 -14.5t34 20.5t-18 52zM895 814q-8 -8 -19.5 -8t-18.5 8q-8 8 -8 19t8 18q7 8 18.5 8t19.5 -8q7 -7 7 -18t-7 -19zM1060 740l-35 -35q-12 -13 -29.5 -13t-30.5 13l-38 38q-12 13 -12 30t12 30l35 35q12 12 29.5 12
+t30.5 -12l38 -39q12 -12 12 -29.5t-12 -29.5zM951 870q-7 -8 -18.5 -8t-19.5 8q-7 8 -7 19t7 19q8 8 19 8t19 -8t8 -19t-8 -19zM1354 968q-34 -64 -107.5 -85.5t-127.5 16.5q-38 28 -61 66.5t-21 87.5t39 92t75.5 53t70.5 -5t70 -51q2 -2 13 -12.5t14.5 -13.5t13 -13.5
+t12.5 -15.5t10 -15.5t8.5 -18t4 -18.5t1 -21t-5 -22t-9.5 -24zM1555 486q3 20 -8.5 34.5t-27.5 21.5t-33 17t-23 20q-40 71 -84 98.5t-113 11.5q19 13 40 18.5t33 4.5l12 -1q2 45 -34 90q6 20 6.5 40.5t-2.5 30.5l-3 10q43 24 71 65t34 91q10 84 -43 150.5t-137 76.5
+q-60 7 -114 -18.5t-82 -74.5q-30 -51 -33.5 -101t14.5 -87t43.5 -64t56.5 -42q-45 4 -88 36t-57 88q-28 108 32 222q-16 21 -29 32q-50 0 -89 -19q19 24 42 37t36 14l13 1q0 50 -13 78q-10 21 -32.5 28.5t-47 -3.5t-37.5 -40q2 4 4 7q-7 -28 -6.5 -75.5t19 -117t48.5 -122.5
+q-25 -14 -47 -36q-35 -16 -85.5 -70.5t-84.5 -101.5l-33 -46q-90 -34 -181 -125.5t-75 -162.5q1 -16 11 -27q-15 -12 -30 -30q-21 -25 -21 -54t21.5 -40t63.5 6q41 19 77 49.5t55 60.5q-2 2 -6.5 5t-20.5 7.5t-33 3.5q23 5 51 12.5t40 10t27.5 6t26 4t23.5 0.5q14 -7 22 34
+q7 37 7 90q0 102 -40 150q106 -103 101 -219q-1 -29 -15 -50t-27 -27l-13 -6q-4 -7 -19 -32t-26 -45.5t-26.5 -52t-25 -61t-17 -63t-6.5 -66.5t10 -63q-35 54 -37 80q-22 -24 -34.5 -39t-33.5 -42t-30.5 -46t-16.5 -41t-0.5 -38t25.5 -27q45 -25 144 64t190.5 221.5
+t122.5 228.5q86 52 145 115.5t86 119.5q47 -93 154 -178q104 -83 167 -80q39 2 46 43zM1794 640q0 -182 -71 -348t-191 -286t-286.5 -191t-348.5 -71t-348.5 71t-286.5 191t-191 286t-71 348t71 348t191 286t286.5 191t348.5 71t348.5 -71t286.5 -191t191 -286t71 -348z" />
+    <glyph glyph-name="uniF2D7" unicode="&#xf2d7;" 
+d="M518 1353v-655q103 -1 191.5 1.5t125.5 5.5l37 3q68 2 90.5 24.5t39.5 94.5l33 142h103l-14 -322l7 -319h-103l-29 127q-15 68 -45 93t-84 26q-87 8 -352 8v-556q0 -78 43.5 -115.5t133.5 -37.5h357q35 0 59.5 2t55 7.5t54 18t48.5 32t46 50.5t39 73l93 216h89
+q-6 -37 -31.5 -252t-30.5 -276q-146 5 -263.5 8t-162.5 4h-44h-628l-376 -12v102l127 25q67 13 91.5 37t25.5 79l8 643q3 402 -8 645q-2 61 -25.5 84t-91.5 36l-127 24v102l376 -12h702q139 0 374 27q-6 -68 -14 -194.5t-12 -219.5l-5 -92h-93l-32 124q-31 121 -74 179.5
+t-113 58.5h-548q-28 0 -35.5 -8.5t-7.5 -30.5z" />
+    <glyph glyph-name="uniF2D8" unicode="&#xf2d8;" 
+d="M922 739v-182q0 -4 0.5 -15t0 -15l-1.5 -12t-3.5 -11.5t-6.5 -7.5t-11 -5.5t-16 -1.5v309q9 0 16 -1t11 -5t6.5 -5.5t3.5 -9.5t1 -10.5v-13.5v-14zM1238 643v-121q0 -1 0.5 -12.5t0 -15.5t-2.5 -11.5t-7.5 -10.5t-13.5 -3q-9 0 -14 9q-4 10 -4 165v7v8.5v9t1.5 8.5l3.5 7
+t5 5.5t8 1.5q6 0 10 -1.5t6.5 -4.5t4 -6t2 -8.5t0.5 -8v-9.5v-9zM180 407h122v472h-122v-472zM614 407h106v472h-159l-28 -221q-20 148 -32 221h-158v-472h107v312l45 -312h76l43 319v-319zM1039 712q0 67 -5 90q-3 16 -11 28.5t-17 20.5t-25 14t-26.5 8.5t-31 4t-29 1.5
+h-29.5h-12h-91v-472h56q169 -1 197 24.5t25 180.5q-1 62 -1 100zM1356 515v133q0 29 -2 45t-9.5 33.5t-24.5 25t-46 7.5q-46 0 -77 -34v154h-117v-472h110l7 30q30 -36 77 -36q50 0 66 30.5t16 83.5zM1536 1248v-1216q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113
+v1216q0 66 47 113t113 47h1216q66 0 113 -47t47 -113z" />
+    <glyph glyph-name="uniF2D9" unicode="&#xf2d9;" horiz-adv-x="2176" 
+d="M1143 -197q-6 1 -11 4q-13 8 -36 23t-86 65t-116.5 104.5t-112 140t-89.5 172.5q-17 3 -175 37q66 -213 235 -362t391 -184zM502 409l168 -28q-25 76 -41 167.5t-19 145.5l-4 53q-84 -82 -121 -224q5 -65 17 -114zM612 1018q-43 -64 -77 -148q44 46 74 68zM2049 584
+q0 161 -62 307t-167.5 252t-250.5 168.5t-304 62.5q-147 0 -281 -52.5t-240 -148.5q-30 -58 -45 -160q60 51 143 83.5t158.5 43t143 13.5t108.5 -1l40 -3q33 -1 53 -15.5t24.5 -33t6.5 -37t-1 -28.5q-126 11 -227.5 0.5t-183 -43.5t-142.5 -71.5t-131 -98.5
+q4 -36 11.5 -92.5t35.5 -178t62 -179.5q123 -6 247.5 14.5t214.5 53.5t162.5 67t109.5 59l37 24q22 16 39.5 20.5t30.5 -5t17 -34.5q14 -97 -39 -121q-208 -97 -467 -134q-135 -20 -317 -16q41 -96 110 -176.5t137 -127t130.5 -79t101.5 -43.5l39 -12q143 -23 263 15
+q195 99 314 289t119 418zM2123 621q-14 -135 -40 -212q-70 -208 -181.5 -346.5t-318.5 -253.5q-48 -33 -82 -44q-72 -26 -163 -16q-36 -3 -73 -3q-283 0 -504.5 173t-295.5 442q-1 0 -4 0.5t-5 0.5q-6 -50 2.5 -112.5t26 -115t36 -98t31.5 -71.5l14 -26q8 -12 54 -82
+q-71 38 -124.5 106.5t-78.5 140t-39.5 137t-17.5 107.5l-2 42q-5 2 -33.5 12.5t-48.5 18t-53 20.5t-57.5 25t-50 25.5t-42.5 27t-25 25.5q19 -10 50.5 -25.5t113 -45.5t145.5 -38l2 32q11 149 94 290q41 202 176 365q28 115 81 214q15 28 32 45t49 32q158 74 303.5 104
+t302 11t306.5 -97q220 -115 333 -336t87 -474z" />
+    <glyph glyph-name="uniF2DA" unicode="&#xf2da;" horiz-adv-x="1792" 
+d="M1341 752q29 44 -6.5 129.5t-121.5 142.5q-58 39 -125.5 53.5t-118 4.5t-68.5 -37q-12 -23 -4.5 -28t42.5 -10q23 -3 38.5 -5t44.5 -9.5t56 -17.5q36 -13 67.5 -31.5t53 -37t40 -38.5t30.5 -38t22 -34.5t16.5 -28.5t12 -18.5t10.5 -6t11 9.5zM1704 178
+q-52 -127 -148.5 -220t-214.5 -141.5t-253 -60.5t-266 13.5t-251 91t-210 161.5t-141.5 235.5t-46.5 303.5q1 41 8.5 84.5t12.5 64t24 80.5t23 73q-51 -208 1 -397t173 -318t291 -206t346 -83t349 74.5t289 244.5q20 27 18 14q0 -4 -4 -14zM1465 627q0 -104 -40.5 -199
+t-108.5 -164t-162 -109.5t-198 -40.5t-198 40.5t-162 109.5t-108.5 164t-40.5 199t40.5 199t108.5 164t162 109.5t198 40.5t198 -40.5t162 -109.5t108.5 -164t40.5 -199zM1752 915q-65 147 -180.5 251t-253 153.5t-292 53.5t-301 -36.5t-275.5 -129t-220 -211.5t-131 -297
+t-10 -373q-49 161 -51.5 311.5t35.5 272.5t109 227t165.5 180.5t207 126t232 71t242.5 9t236 -54t216 -124.5t178 -197q33 -50 62 -121t31 -112zM1690 573q12 244 -136.5 416t-396.5 240q-8 0 -10 5t24 8q125 -4 230 -50t173 -120t116 -168.5t58.5 -199t-1 -208
+t-61.5 -197.5t-122.5 -167t-185 -117.5t-248.5 -46.5q108 30 201.5 80t174 123t129.5 176.5t55 225.5z" />
+    <glyph glyph-name="uniF2DB" unicode="&#xf2db;" 
+d="M192 256v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 512v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 768v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16
+q0 16 16 16h112zM192 1024v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 1280v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM1280 1440v-1472q0 -40 -28 -68t-68 -28h-832q-40 0 -68 28
+t-28 68v1472q0 40 28 68t68 28h832q40 0 68 -28t28 -68zM1536 208v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 464v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 720v-32
+q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 976v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 1232v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16
+h48q16 0 16 -16z" />
+    <glyph glyph-name="uniF2DC" unicode="&#xf2dc;" horiz-adv-x="1664" 
+d="M1566 419l-167 -33l186 -107q23 -13 29.5 -38.5t-6.5 -48.5q-14 -23 -39 -29.5t-48 6.5l-186 106l55 -160q13 -38 -12 -63.5t-60.5 -20.5t-48.5 42l-102 300l-271 156v-313l208 -238q16 -18 17 -39t-11 -36.5t-28.5 -25t-37 -5.5t-36.5 22l-112 128v-214q0 -26 -19 -45
+t-45 -19t-45 19t-19 45v214l-112 -128q-16 -18 -36.5 -22t-37 5.5t-28.5 25t-11 36.5t17 39l208 238v313l-271 -156l-102 -300q-13 -37 -48.5 -42t-60.5 20.5t-12 63.5l55 160l-186 -106q-23 -13 -48 -6.5t-39 29.5q-13 23 -6.5 48.5t29.5 38.5l186 107l-167 33
+q-29 6 -42 29t-8.5 46.5t25.5 40t50 10.5l310 -62l271 157l-271 157l-310 -62q-4 -1 -13 -1q-27 0 -44 18t-19 40t11 43t40 26l167 33l-186 107q-23 13 -29.5 38.5t6.5 48.5t39 30t48 -7l186 -106l-55 160q-13 38 12 63.5t60.5 20.5t48.5 -42l102 -300l271 -156v313
+l-208 238q-16 18 -17 39t11 36.5t28.5 25t37 5.5t36.5 -22l112 -128v214q0 26 19 45t45 19t45 -19t19 -45v-214l112 128q16 18 36.5 22t37 -5.5t28.5 -25t11 -36.5t-17 -39l-208 -238v-313l271 156l102 300q13 37 48.5 42t60.5 -20.5t12 -63.5l-55 -160l186 106
+q23 13 48 6.5t39 -29.5q13 -23 6.5 -48.5t-29.5 -38.5l-186 -107l167 -33q27 -5 40 -26t11 -43t-19 -40t-44 -18q-9 0 -13 1l-310 62l-271 -157l271 -157l310 62q29 6 50 -10.5t25.5 -40t-8.5 -46.5t-42 -29z" />
+    <glyph glyph-name="uniF2DD" unicode="&#xf2dd;" horiz-adv-x="1792" 
+d="M1473 607q7 118 -33 226.5t-113 189t-177 131t-221 57.5q-116 7 -225.5 -32t-192 -110.5t-135 -175t-59.5 -220.5q-7 -118 33 -226.5t113 -189t177.5 -131t221.5 -57.5q155 -9 293 59t224 195.5t94 283.5zM1792 1536l-349 -348q120 -117 180.5 -272t50.5 -321
+q-11 -183 -102 -339t-241 -255.5t-332 -124.5l-999 -132l347 347q-120 116 -180.5 271.5t-50.5 321.5q11 184 102 340t241.5 255.5t332.5 124.5q167 22 500 66t500 66z" />
+    <glyph glyph-name="uniF2DE" unicode="&#xf2de;" horiz-adv-x="1792" 
+d="M948 508l163 -329h-51l-175 350l-171 -350h-49l179 374l-78 33l21 49l240 -102l-21 -50zM563 1100l304 -130l-130 -304l-304 130zM907 915l240 -103l-103 -239l-239 102zM1188 765l191 -81l-82 -190l-190 81zM1680 640q0 159 -62 304t-167.5 250.5t-250.5 167.5t-304 62
+t-304 -62t-250.5 -167.5t-167.5 -250.5t-62 -304t62 -304t167.5 -250.5t250.5 -167.5t304 -62t304 62t250.5 167.5t167.5 250.5t62 304zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71
+t286 -191t191 -286t71 -348z" />
+    <glyph glyph-name="uniF2E0" unicode="&#xf2e0;" horiz-adv-x="1920" 
+d="M1334 302q-4 24 -27.5 34t-49.5 10.5t-48.5 12.5t-25.5 38q-5 47 33 139.5t75 181t32 127.5q-14 101 -117 103q-45 1 -75 -16l-3 -2l-5 -2.5t-4.5 -2t-5 -2t-5 -0.5t-6 1.5t-6 3.5t-6.5 5q-3 2 -9 8.5t-9 9t-8.5 7.5t-9.5 7.5t-9.5 5.5t-11 4.5t-11.5 2.5q-30 5 -48 -3
+t-45 -31q-1 -1 -9 -8.5t-12.5 -11t-15 -10t-16.5 -5.5t-17 3q-54 27 -84 40q-41 18 -94 -5t-76 -65q-16 -28 -41 -98.5t-43.5 -132.5t-40 -134t-21.5 -73q-22 -69 18.5 -119t110.5 -46q30 2 50.5 15t38.5 46q7 13 79 199.5t77 194.5q6 11 21.5 18t29.5 0q27 -15 21 -53
+q-2 -18 -51 -139.5t-50 -132.5q-6 -38 19.5 -56.5t60.5 -7t55 49.5q4 8 45.5 92t81.5 163.5t46 88.5q20 29 41 28q29 0 25 -38q-2 -16 -65.5 -147.5t-70.5 -159.5q-12 -53 13 -103t74 -74q17 -9 51 -15.5t71.5 -8t62.5 14t20 48.5zM383 86q3 -15 -5 -27.5t-23 -15.5
+q-14 -3 -26.5 5t-15.5 23q-3 14 5 27t22 16t27 -5t16 -23zM953 -177q12 -17 8.5 -37.5t-20.5 -32.5t-37.5 -8t-32.5 21q-11 17 -7.5 37.5t20.5 32.5t37.5 8t31.5 -21zM177 635q-18 -27 -49.5 -33t-57.5 13q-26 18 -32 50t12 58q18 27 49.5 33t57.5 -12q26 -19 32 -50.5
+t-12 -58.5zM1467 -42q19 -28 13 -61.5t-34 -52.5t-60.5 -13t-51.5 34t-13 61t33 53q28 19 60.5 13t52.5 -34zM1579 562q69 -113 42.5 -244.5t-134.5 -207.5q-90 -63 -199 -60q-20 -80 -84.5 -127t-143.5 -44.5t-140 57.5q-12 -9 -13 -10q-103 -71 -225 -48.5t-193 126.5
+q-50 73 -53 164q-83 14 -142.5 70.5t-80.5 128t-2 152t81 138.5q-36 60 -38 128t24.5 125t79.5 98.5t121 50.5q32 85 99 148t146.5 91.5t168 17t159.5 -66.5q72 21 140 17.5t128.5 -36t104.5 -80t67.5 -115t17.5 -140.5q52 -16 87 -57t45.5 -89t-5.5 -99.5t-58 -87.5z
+M455 1222q14 -20 9.5 -44.5t-24.5 -38.5q-19 -14 -43.5 -9.5t-37.5 24.5q-14 20 -9.5 44.5t24.5 38.5q19 14 43.5 9.5t37.5 -24.5zM614 1503q4 -16 -5 -30.5t-26 -18.5t-31 5.5t-18 26.5q-3 17 6.5 31t25.5 18q17 4 31 -5.5t17 -26.5zM1800 555q4 -20 -6.5 -37t-30.5 -21
+q-19 -4 -36 6.5t-21 30.5t6.5 37t30.5 22q20 4 36.5 -7.5t20.5 -30.5zM1136 1448q16 -27 8.5 -58.5t-35.5 -47.5q-27 -16 -57.5 -8.5t-46.5 34.5q-16 28 -8.5 59t34.5 48t58 9t47 -36zM1882 792q4 -15 -4 -27.5t-23 -16.5q-15 -3 -27.5 5.5t-15.5 22.5q-3 15 5 28t23 16
+q14 3 26.5 -5t15.5 -23zM1691 1033q15 -22 10.5 -49t-26.5 -43q-22 -15 -49 -10t-42 27t-10 49t27 43t48.5 11t41.5 -28z" />
+    <glyph glyph-name="uniF2E1" unicode="&#xf2e1;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2E2" unicode="&#xf2e2;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2E3" unicode="&#xf2e3;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2E4" unicode="&#xf2e4;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2E5" unicode="&#xf2e5;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2E6" unicode="&#xf2e6;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2E7" unicode="&#xf2e7;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="_698" unicode="&#xf2e8;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2E9" unicode="&#xf2e9;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2EA" unicode="&#xf2ea;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2EB" unicode="&#xf2eb;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2EC" unicode="&#xf2ec;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2ED" unicode="&#xf2ed;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="uniF2EE" unicode="&#xf2ee;" horiz-adv-x="1792" 
+ />
+    <glyph glyph-name="lessequal" unicode="&#xf500;" horiz-adv-x="1792" 
+ />
+  </font>
+</defs></svg>
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.ttf b/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.ttf
new file mode 100644 (file)
index 0000000..35acda2
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.ttf differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff b/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff
new file mode 100644 (file)
index 0000000..400014a
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff2 b/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff2
new file mode 100644 (file)
index 0000000..4d13fc6
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff2 differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff
new file mode 100644 (file)
index 0000000..88ad05b
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff2 b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff2
new file mode 100644 (file)
index 0000000..c4e3d80
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff2 differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff
new file mode 100644 (file)
index 0000000..c6dff51
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff2 b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff2
new file mode 100644 (file)
index 0000000..bb19504
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff2 differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff
new file mode 100644 (file)
index 0000000..76114bc
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff2 b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff2
new file mode 100644 (file)
index 0000000..3404f37
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff2 differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff
new file mode 100644 (file)
index 0000000..ae1307f
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff2 b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff2
new file mode 100644 (file)
index 0000000..3bf9843
Binary files /dev/null and b/doc/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff2 differ
index a2d7c0f..8cd4f10 100644 (file)
@@ -1,5 +1,4 @@
-*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,.rst-content .toctree-wrapper p.caption,h3{orphans:3;widows:3}h2,.rst-content .toctree-wrapper p.caption,h3{page-break-after:avoid}}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*!
- *  Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome
+html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before,.wy-nav-top a,.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*!
+ *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
  *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.2.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.2.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.2.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.wy-menu-vertical li span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.rst-content code.download span.pull-left:first-child,.pull-left.icon{margin-right:.3em}.fa.pull-right,.wy-menu-vertical li span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.rst-content code.download span.pull-right:first-child,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .rst-content p.caption .headerlink,.rst-content p.caption a .headerlink,a .rst-content tt.download span:first-child,.rst-content tt.download a span:first-child,a .rst-content code.download span:first-child,.rst-content code.download a span:first-child,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .btn span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.btn .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .rst-content p.caption .headerlink,.rst-content p.caption .btn .headerlink,.btn .rst-content tt.download span:first-child,.rst-content tt.download .btn span:first-child,.btn .rst-content code.download span:first-child,.rst-content code.download .btn span:first-child,.btn .icon,.nav .fa,.nav .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand,.nav .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .rst-content p.caption .headerlink,.rst-content p.caption .nav .headerlink,.nav .rst-content tt.download span:first-child,.rst-content tt.download .nav span:first-child,.nav .rst-content code.download span:first-child,.rst-content code.download .nav span:first-child,.nav .icon{display:inline}.btn .fa.fa-large,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .btn span.fa-large:first-child,.btn .rst-content code.download span.fa-large:first-child,.rst-content code.download .btn span.fa-large:first-child,.btn .fa-large.icon,.nav .fa.fa-large,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.nav .rst-content code.download span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .btn span.fa-spin:first-child,.btn .rst-content code.download span.fa-spin:first-child,.rst-content code.download .btn span.fa-spin:first-child,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.nav .rst-content code.download span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.wy-menu-vertical li span.btn.toctree-expand:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.rst-content code.download span.btn:first-child:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.rst-content code.download span.btn:first-child:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.rst-content tt.download .btn-mini span:first-child:before,.btn-mini .rst-content code.download span:first-child:before,.rst-content code.download .btn-mini span:first-child:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:0.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{width:36px;height:12px;margin:12px 0;position:relative;border-radius:4px;background:#ccc;cursor:pointer;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:before{position:absolute;content:"";display:block;width:18px;height:18px;border-radius:4px;background:#999;left:-3px;top:-3px;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:after{content:"false";position:absolute;left:48px;display:block;font-size:12px;color:#ccc}.wy-switch.active{background:#1e8449}.wy-switch.active:before{left:24px;background:#27AE60}.wy-switch.active:after{content:"true"}.wy-switch.disabled,.wy-switch.active.disabled{cursor:not-allowed}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,.rst-content .toctree-wrapper p.caption,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2,.rst-content .toctree-wrapper p.caption{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt,.rst-content code{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9B59B6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#EAF2F5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs li code,.wy-breadcrumbs li .rst-content tt,.rst-content .wy-breadcrumbs li tt{padding:5px;border:none;background:none}.wy-breadcrumbs li code.literal,.wy-breadcrumbs li .rst-content tt.literal,.rst-content .wy-breadcrumbs li tt.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;margin-bottom:0;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#555;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li code,.wy-menu-vertical li .rst-content tt,.rst-content .wy-menu-vertical li tt{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:0.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.on a:hover span.toctree-expand,.wy-menu-vertical li.current>a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand{display:block;font-size:0.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current li.toctree-l2>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>ul{display:none}.wy-menu-vertical li.toctree-l1.current li.toctree-l2.current>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3.current>ul{display:block}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{display:block;background:#c9c9c9;padding:0.4045em 4.045em}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3{font-size:0.9em}.wy-menu-vertical li.toctree-l3.current>a{background:#bdbdbd;padding:0.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{display:block;background:#bdbdbd;padding:0.4045em 5.663em;border-top:none;border-bottom:none}.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.toctree-l4{font-size:0.9em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#b3b3b3}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:0.809em;margin-bottom:0.809em;z-index:200;background-color:#2980B9;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-side-nav-search>a img.logo,.wy-side-nav-search .wy-dropdown>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search>a.icon img.logo,.wy-side-nav-search .wy-dropdown>a.icon img.logo{margin-top:0.85em}.wy-side-nav-search>div.version{margin-top:-0.4045em;margin-bottom:0.809em;font-weight:normal;color:rgba(255,255,255,0.3)}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}footer span.commit code,footer span.commit .rst-content tt,.rst-content footer span.commit tt{padding:0px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:1em;background:none;border:none;color:#999}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-side-scroll{width:auto}.wy-side-nav-search{width:auto}.wy-menu.wy-menu-vertical{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content .toctree-wrapper p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content .toctree-wrapper p.caption .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content p.caption .headerlink:after{visibility:visible;content:"";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content .toctree-wrapper p.caption:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink,.rst-content p.caption:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.docutils.citation tt,.rst-content table.docutils.citation code,.rst-content table.docutils.footnote tt,.rst-content table.docutils.footnote code{color:#555}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt,.rst-content tt,.rst-content code{color:#000;padding:2px 5px}.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important;line-height:normal}.rst-content tt.literal,.rst-content tt.literal,.rst-content code.literal{color:#E74C3C}.rst-content tt.xref,a .rst-content tt,.rst-content tt.xref,.rst-content code.xref,a .rst-content tt,a .rst-content code{font-weight:bold;color:#404040}.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:#555}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) code{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) code.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}.rst-content tt.download,.rst-content code.download{background:inherit;padding:inherit;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:400;src:local("Inconsolata"),local("Inconsolata-Regular"),url(../fonts/Inconsolata-Regular.ttf) format("truetype")}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:700;src:local("Inconsolata Bold"),local("Inconsolata-Bold"),url(../fonts/Inconsolata-Bold.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:400;src:local("Lato Regular"),local("Lato-Regular"),url(../fonts/Lato-Regular.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:700;src:local("Lato Bold"),local("Lato-Bold"),url(../fonts/Lato-Bold.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:400;src:local("Roboto Slab Regular"),local("RobotoSlab-Regular"),url(../fonts/RobotoSlab-Regular.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:700;src:local("Roboto Slab Bold"),local("RobotoSlab-Bold"),url(../fonts/RobotoSlab-Bold.ttf) format("truetype")}
-/*# sourceMappingURL=theme.css.map */
+ */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p.caption .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a span.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-left.toctree-expand,.wy-menu-vertical li span.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p.caption .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a span.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-right.toctree-expand,.wy-menu-vertical li span.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li span.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li span.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li span.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p.caption .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.btn .wy-menu-vertical li span.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p.caption .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.nav .wy-menu-vertical li span.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p.caption .btn .headerlink,.rst-content p.caption .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li span.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol li,.rst-content ol.arabic li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content ol.arabic li p:last-child,.rst-content ol.arabic li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.rst-content .wy-breadcrumbs li tt,.wy-breadcrumbs li .rst-content tt,.wy-breadcrumbs li code{padding:5px;border:none;background:none}.rst-content .wy-breadcrumbs li tt.literal,.wy-breadcrumbs li .rst-content tt.literal,.wy-breadcrumbs li code.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover span.toctree-expand,.wy-menu-vertical li.on a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand{display:block;font-size:.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content img{max-width:100%;height:auto}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp{user-select:none;pointer-events:none}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink{visibility:hidden;font-size:14px}.rst-content .code-block-caption .headerlink:after,.rst-content .toctree-wrapper>p.caption .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content table>caption .headerlink:after{content:"\f0c1";font-family:FontAwesome}.rst-content .code-block-caption:hover .headerlink:after,.rst-content .toctree-wrapper>p.caption:hover .headerlink:after,.rst-content dl dt:hover .headerlink:after,.rst-content h1:hover .headerlink:after,.rst-content h2:hover .headerlink:after,.rst-content h3:hover .headerlink:after,.rst-content h4:hover .headerlink:after,.rst-content h5:hover .headerlink:after,.rst-content h6:hover .headerlink:after,.rst-content p.caption:hover .headerlink:after,.rst-content table>caption:hover .headerlink:after{visibility:visible}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl dt span.classifier:before{content:" : "}html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.field-list>dt:after,html.writer-html5 .rst-content dl.footnote>dt:after{content:":"}html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code,html.writer-html4 .rst-content dl:not(.docutils) tt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block}
\ No newline at end of file
diff --git a/doc/_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf b/doc/_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf
deleted file mode 100644 (file)
index 81c9ad9..0000000
Binary files a/doc/_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf and /dev/null differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot b/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot
deleted file mode 100644 (file)
index 84677bc..0000000
Binary files a/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot and /dev/null differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg b/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg
deleted file mode 100644 (file)
index d907b25..0000000
+++ /dev/null
@@ -1,520 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
-<svg xmlns="http://www.w3.org/2000/svg">
-<metadata></metadata>
-<defs>
-<font id="fontawesomeregular" horiz-adv-x="1536" >
-<font-face units-per-em="1792" ascent="1536" descent="-256" />
-<missing-glyph horiz-adv-x="448" />
-<glyph unicode=" "  horiz-adv-x="448" />
-<glyph unicode="&#x09;" horiz-adv-x="448" />
-<glyph unicode="&#xa0;" horiz-adv-x="448" />
-<glyph unicode="&#xa8;" horiz-adv-x="1792" />
-<glyph unicode="&#xa9;" horiz-adv-x="1792" />
-<glyph unicode="&#xae;" horiz-adv-x="1792" />
-<glyph unicode="&#xb4;" horiz-adv-x="1792" />
-<glyph unicode="&#xc6;" horiz-adv-x="1792" />
-<glyph unicode="&#xd8;" horiz-adv-x="1792" />
-<glyph unicode="&#x2000;" horiz-adv-x="768" />
-<glyph unicode="&#x2001;" horiz-adv-x="1537" />
-<glyph unicode="&#x2002;" horiz-adv-x="768" />
-<glyph unicode="&#x2003;" horiz-adv-x="1537" />
-<glyph unicode="&#x2004;" horiz-adv-x="512" />
-<glyph unicode="&#x2005;" horiz-adv-x="384" />
-<glyph unicode="&#x2006;" horiz-adv-x="256" />
-<glyph unicode="&#x2007;" horiz-adv-x="256" />
-<glyph unicode="&#x2008;" horiz-adv-x="192" />
-<glyph unicode="&#x2009;" horiz-adv-x="307" />
-<glyph unicode="&#x200a;" horiz-adv-x="85" />
-<glyph unicode="&#x202f;" horiz-adv-x="307" />
-<glyph unicode="&#x205f;" horiz-adv-x="384" />
-<glyph unicode="&#x2122;" horiz-adv-x="1792" />
-<glyph unicode="&#x221e;" horiz-adv-x="1792" />
-<glyph unicode="&#x2260;" horiz-adv-x="1792" />
-<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
-<glyph unicode="&#xf000;" horiz-adv-x="1792" d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
-<glyph unicode="&#xf001;" d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf002;" horiz-adv-x="1664" d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
-<glyph unicode="&#xf003;" horiz-adv-x="1792" d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf004;" horiz-adv-x="1792" d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 q-18 -18 -44 -18z" />
-<glyph unicode="&#xf005;" horiz-adv-x="1664" d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z" />
-<glyph unicode="&#xf006;" horiz-adv-x="1664" d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
-<glyph unicode="&#xf007;" horiz-adv-x="1408" d="M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
-<glyph unicode="&#xf008;" horiz-adv-x="1920" d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf009;" horiz-adv-x="1664" d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf00a;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf00b;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf00c;" horiz-adv-x="1792" d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
-<glyph unicode="&#xf00d;" horiz-adv-x="1408" d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
-<glyph unicode="&#xf00e;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
-<glyph unicode="&#xf010;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z " />
-<glyph unicode="&#xf011;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
-<glyph unicode="&#xf012;" horiz-adv-x="1792" d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf013;" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
-<glyph unicode="&#xf014;" horiz-adv-x="1408" d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf015;" horiz-adv-x="1664" d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
-<glyph unicode="&#xf016;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z " />
-<glyph unicode="&#xf017;" d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf018;" horiz-adv-x="1920" d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
-<glyph unicode="&#xf019;" horiz-adv-x="1664" d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
-<glyph unicode="&#xf01a;" d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf01b;" d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf01c;" d="M1023 576h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8t-2.5 -8h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 q25 -61 25 -123z" />
-<glyph unicode="&#xf01d;" d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf01e;" d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9 l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
-<glyph unicode="&#xf021;" d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
-<glyph unicode="&#xf022;" horiz-adv-x="1792" d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z" />
-<glyph unicode="&#xf023;" horiz-adv-x="1152" d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf024;" horiz-adv-x="1792" d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf025;" horiz-adv-x="1664" d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
-<glyph unicode="&#xf026;" horiz-adv-x="768" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
-<glyph unicode="&#xf027;" horiz-adv-x="1152" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
-<glyph unicode="&#xf028;" horiz-adv-x="1664" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
-<glyph unicode="&#xf029;" horiz-adv-x="1408" d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
-<glyph unicode="&#xf02a;" horiz-adv-x="1792" d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
-<glyph unicode="&#xf02b;" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91z" />
-<glyph unicode="&#xf02c;" horiz-adv-x="1920" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
-<glyph unicode="&#xf02d;" horiz-adv-x="1664" d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
-<glyph unicode="&#xf02e;" horiz-adv-x="1280" d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
-<glyph unicode="&#xf02f;" horiz-adv-x="1664" d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
-<glyph unicode="&#xf030;" horiz-adv-x="1920" d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-<glyph unicode="&#xf031;" horiz-adv-x="1664" d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57 q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -4 -0.5 -13t-0.5 -13q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5 q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" />
-<glyph unicode="&#xf032;" horiz-adv-x="1408" d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142 q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5 t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68.5 -0.5t67.5 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5 t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" />
-<glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q6 2 81.5 21.5t111.5 37.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
-<glyph unicode="&#xf034;" horiz-adv-x="1792" d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2 t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5 q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" />
-<glyph unicode="&#xf035;" d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1 t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5 t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49 t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" />
-<glyph unicode="&#xf036;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf037;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf038;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf039;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf03a;" horiz-adv-x="1792" d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
-<glyph unicode="&#xf03b;" horiz-adv-x="1792" d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
-<glyph unicode="&#xf03c;" horiz-adv-x="1792" d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
-<glyph unicode="&#xf03d;" horiz-adv-x="1792" d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z" />
-<glyph unicode="&#xf03e;" horiz-adv-x="1920" d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf040;" d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 q53 0 91 -38l235 -234q37 -39 37 -91z" />
-<glyph unicode="&#xf041;" horiz-adv-x="1024" d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
-<glyph unicode="&#xf042;" d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf043;" horiz-adv-x="1024" d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
-<glyph unicode="&#xf044;" horiz-adv-x="1792" d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
-<glyph unicode="&#xf045;" horiz-adv-x="1664" d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
-<glyph unicode="&#xf046;" horiz-adv-x="1664" d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z" />
-<glyph unicode="&#xf047;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
-<glyph unicode="&#xf048;" horiz-adv-x="1024" d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19z" />
-<glyph unicode="&#xf049;" horiz-adv-x="1792" d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z" />
-<glyph unicode="&#xf04a;" horiz-adv-x="1664" d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z" />
-<glyph unicode="&#xf04b;" horiz-adv-x="1408" d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
-<glyph unicode="&#xf04c;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf04d;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf04e;" horiz-adv-x="1664" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
-<glyph unicode="&#xf050;" horiz-adv-x="1792" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710 q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
-<glyph unicode="&#xf051;" horiz-adv-x="1024" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19z" />
-<glyph unicode="&#xf052;" horiz-adv-x="1538" d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
-<glyph unicode="&#xf053;" horiz-adv-x="1280" d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" />
-<glyph unicode="&#xf054;" horiz-adv-x="1280" d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" />
-<glyph unicode="&#xf055;" d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf056;" d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" />
-<glyph unicode="&#xf057;" d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf058;" d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf059;" d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf05a;" d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf05b;" d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf05c;" d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf05d;" d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf05e;" d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
-<glyph unicode="&#xf060;" d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 t32.5 -90.5z" />
-<glyph unicode="&#xf061;" d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
-<glyph unicode="&#xf062;" horiz-adv-x="1664" d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 q37 -39 37 -91z" />
-<glyph unicode="&#xf063;" horiz-adv-x="1664" d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
-<glyph unicode="&#xf064;" horiz-adv-x="1792" d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
-<glyph unicode="&#xf065;" d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf066;" d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
-<glyph unicode="&#xf067;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf068;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf069;" horiz-adv-x="1664" d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
-<glyph unicode="&#xf06a;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
-<glyph unicode="&#xf06b;" d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf06c;" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
-<glyph unicode="&#xf06d;" horiz-adv-x="1408" d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
-<glyph unicode="&#xf06e;" horiz-adv-x="1792" d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
-<glyph unicode="&#xf070;" horiz-adv-x="1792" d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z " />
-<glyph unicode="&#xf071;" horiz-adv-x="1792" d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
-<glyph unicode="&#xf072;" horiz-adv-x="1408" d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
-<glyph unicode="&#xf073;" horiz-adv-x="1664" d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf074;" horiz-adv-x="1792" d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
-<glyph unicode="&#xf075;" horiz-adv-x="1792" d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
-<glyph unicode="&#xf076;" d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf077;" horiz-adv-x="1792" d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
-<glyph unicode="&#xf078;" horiz-adv-x="1792" d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
-<glyph unicode="&#xf079;" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " />
-<glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5 l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5 t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
-<glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
-<glyph unicode="&#xf07d;" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
-<glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
-<glyph unicode="&#xf080;" horiz-adv-x="2048" d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
-<glyph unicode="&#xf081;" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf082;" d="M1536 160q0 -119 -84.5 -203.5t-203.5 -84.5h-192v608h203l30 224h-233v143q0 54 28 83t96 29l132 1v207q-96 9 -180 9q-136 0 -218 -80.5t-82 -225.5v-166h-224v-224h224v-608h-544q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 q119 0 203.5 -84.5t84.5 -203.5v-960z" />
-<glyph unicode="&#xf083;" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
-<glyph unicode="&#xf084;" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
-<glyph unicode="&#xf085;" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
-<glyph unicode="&#xf086;" horiz-adv-x="1792" d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
-<glyph unicode="&#xf087;" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
-<glyph unicode="&#xf088;" d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163z" />
-<glyph unicode="&#xf089;" horiz-adv-x="896" d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
-<glyph unicode="&#xf08a;" horiz-adv-x="1792" d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z" />
-<glyph unicode="&#xf08b;" horiz-adv-x="1664" d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
-<glyph unicode="&#xf08c;" d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf08d;" horiz-adv-x="1152" d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
-<glyph unicode="&#xf08e;" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf090;" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf091;" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf092;" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf093;" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
-<glyph unicode="&#xf094;" d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5z" />
-<glyph unicode="&#xf095;" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5 q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174 q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
-<glyph unicode="&#xf096;" horiz-adv-x="1408" d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf097;" horiz-adv-x="1280" d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
-<glyph unicode="&#xf098;" d="M1280 343q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5 t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf099;" horiz-adv-x="1664" d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
-<glyph unicode="&#xf09a;" horiz-adv-x="1024" d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" />
-<glyph unicode="&#xf09b;" d="M1536 640q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf09c;" horiz-adv-x="1664" d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" />
-<glyph unicode="&#xf09d;" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
-<glyph unicode="&#xf09e;" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" />
-<glyph unicode="&#xf0a0;" d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
-<glyph unicode="&#xf0a1;" horiz-adv-x="1792" d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
-<glyph unicode="&#xf0a2;" horiz-adv-x="1792" d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5 t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
-<glyph unicode="&#xf0a3;" d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
-<glyph unicode="&#xf0a4;" horiz-adv-x="1792" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
-<glyph unicode="&#xf0a5;" horiz-adv-x="1792" d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576 q-50 0 -89 -38.5t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45 t45 -19t45 19t19 45zM1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128 q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
-<glyph unicode="&#xf0a6;" d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
-<glyph unicode="&#xf0a7;" d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
-<glyph unicode="&#xf0a8;" d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf0a9;" d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf0aa;" d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf0ab;" d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf0ac;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" />
-<glyph unicode="&#xf0ad;" horiz-adv-x="1664" d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" />
-<glyph unicode="&#xf0ae;" horiz-adv-x="1792" d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19 t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0b0;" horiz-adv-x="1408" d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" />
-<glyph unicode="&#xf0b1;" horiz-adv-x="1792" d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68 t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf0b2;" d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z " />
-<glyph unicode="&#xf0c0;" horiz-adv-x="1920" d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5 t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75 t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5 t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" />
-<glyph unicode="&#xf0c1;" horiz-adv-x="1664" d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26 l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15 t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207 q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" />
-<glyph unicode="&#xf0c2;" horiz-adv-x="1920" d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z " />
-<glyph unicode="&#xf0c3;" horiz-adv-x="1664" d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" />
-<glyph unicode="&#xf0c4;" horiz-adv-x="1792" d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148 q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108 q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6 q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
-<glyph unicode="&#xf0c5;" horiz-adv-x="1792" d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" />
-<glyph unicode="&#xf0c6;" horiz-adv-x="1408" d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181 l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235 z" />
-<glyph unicode="&#xf0c7;" d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" />
-<glyph unicode="&#xf0c8;" d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf0c9;" d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0ca;" horiz-adv-x="1792" d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
-<glyph unicode="&#xf0cb;" horiz-adv-x="1792" d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362 q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5 t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
-<glyph unicode="&#xf0cc;" horiz-adv-x="1792" d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 97 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6 l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -55 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23 l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" />
-<glyph unicode="&#xf0cd;" d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47 q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41 q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472 q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" />
-<glyph unicode="&#xf0ce;" horiz-adv-x="1664" d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 z" />
-<glyph unicode="&#xf0d0;" horiz-adv-x="1664" d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276 l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" />
-<glyph unicode="&#xf0d1;" horiz-adv-x="1792" d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5 t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38 t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0d2;" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134 q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33 q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf0d3;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5 t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5 t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" />
-<glyph unicode="&#xf0d4;" d="M829 318q0 -76 -58.5 -112.5t-139.5 -36.5q-41 0 -80.5 9.5t-75.5 28.5t-58 53t-22 78q0 46 25 80t65.5 51.5t82 25t84.5 7.5q20 0 31 -2q2 -1 23 -16.5t26 -19t23 -18t24.5 -22t19 -22.5t17 -26t9 -26.5t4.5 -31.5zM755 863q0 -60 -33 -99.5t-92 -39.5q-53 0 -93 42.5 t-57.5 96.5t-17.5 106q0 61 32 104t92 43q53 0 93.5 -45t58 -101t17.5 -107zM861 1120l88 64h-265q-85 0 -161 -32t-127.5 -98t-51.5 -153q0 -93 64.5 -154.5t158.5 -61.5q22 0 43 3q-13 -29 -13 -54q0 -44 40 -94q-175 -12 -257 -63q-47 -29 -75.5 -73t-28.5 -95 q0 -43 18.5 -77.5t48.5 -56.5t69 -37t77.5 -21t76.5 -6q60 0 120.5 15.5t113.5 46t86 82.5t33 117q0 49 -20 89.5t-49 66.5t-58 47.5t-49 44t-20 44.5t15.5 42.5t37.5 39.5t44 42t37.5 59.5t15.5 82.5q0 60 -22.5 99.5t-72.5 90.5h83zM1152 672h128v64h-128v128h-64v-128 h-128v-64h128v-160h64v160zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf0d5;" horiz-adv-x="1664" d="M735 740q0 -36 32 -70.5t77.5 -68t90.5 -73.5t77 -104t32 -142q0 -90 -48 -173q-72 -122 -211 -179.5t-298 -57.5q-132 0 -246.5 41.5t-171.5 137.5q-37 60 -37 131q0 81 44.5 150t118.5 115q131 82 404 100q-32 42 -47.5 74t-15.5 73q0 36 21 85q-46 -4 -68 -4 q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q77 66 182.5 98t217.5 32h418l-138 -88h-131q74 -63 112 -133t38 -160q0 -72 -24.5 -129.5t-59 -93t-69.5 -65t-59.5 -61.5t-24.5 -66zM589 836q38 0 78 16.5t66 43.5q53 57 53 159q0 58 -17 125t-48.5 129.5 t-84.5 103.5t-117 41q-42 0 -82.5 -19.5t-65.5 -52.5q-47 -59 -47 -160q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26zM591 -37q58 0 111.5 13t99 39t73 73t27.5 109q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -48 2 q-53 0 -105 -7t-107.5 -25t-97 -46t-68.5 -74.5t-27 -105.5q0 -70 35 -123.5t91.5 -83t119 -44t127.5 -14.5zM1401 839h213v-108h-213v-219h-105v219h-212v108h212v217h105v-217z" />
-<glyph unicode="&#xf0d6;" horiz-adv-x="1920" d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384 v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0d7;" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0d8;" horiz-adv-x="1024" d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-<glyph unicode="&#xf0d9;" horiz-adv-x="640" d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" />
-<glyph unicode="&#xf0da;" horiz-adv-x="640" d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" />
-<glyph unicode="&#xf0db;" horiz-adv-x="1664" d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf0dc;" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-<glyph unicode="&#xf0dd;" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0de;" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-<glyph unicode="&#xf0e0;" horiz-adv-x="1792" d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123 q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" />
-<glyph unicode="&#xf0e1;" d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329 q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" />
-<glyph unicode="&#xf0e2;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" />
-<glyph unicode="&#xf0e3;" horiz-adv-x="1792" d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5 t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14 q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28 q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" />
-<glyph unicode="&#xf0e4;" horiz-adv-x="1792" d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5 t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5 t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29 q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-<glyph unicode="&#xf0e5;" horiz-adv-x="1792" d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640 q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5 t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
-<glyph unicode="&#xf0e6;" horiz-adv-x="1792" d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257 t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5 t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129 q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" />
-<glyph unicode="&#xf0e7;" horiz-adv-x="896" d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" />
-<glyph unicode="&#xf0e8;" horiz-adv-x="1792" d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68 z" />
-<glyph unicode="&#xf0e9;" horiz-adv-x="1664" d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97 q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69 q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" />
-<glyph unicode="&#xf0ea;" horiz-adv-x="1792" d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" />
-<glyph unicode="&#xf0eb;" horiz-adv-x="1024" d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134 q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47 q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5 t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" />
-<glyph unicode="&#xf0ec;" horiz-adv-x="1792" d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9 q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
-<glyph unicode="&#xf0ed;" horiz-adv-x="1920" d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
-<glyph unicode="&#xf0ee;" horiz-adv-x="1920" d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
-<glyph unicode="&#xf0f0;" horiz-adv-x="1408" d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56 t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68 t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 t271.5 -112.5t112.5 -271.5z" />
-<glyph unicode="&#xf0f1;" horiz-adv-x="1408" d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48 t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252 t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" />
-<glyph unicode="&#xf0f2;" horiz-adv-x="1792" d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66 t66 -158z" />
-<glyph unicode="&#xf0f3;" horiz-adv-x="1792" d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5 t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
-<glyph unicode="&#xf0f4;" horiz-adv-x="1920" d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45 t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" />
-<glyph unicode="&#xf0f5;" horiz-adv-x="1408" d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0f6;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704 q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z" />
-<glyph unicode="&#xf0f7;" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0f8;" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5 t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320 v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0f9;" horiz-adv-x="1920" d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152 q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0fa;" horiz-adv-x="1792" d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32 q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" />
-<glyph unicode="&#xf0fb;" horiz-adv-x="1920" d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96 q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93z" />
-<glyph unicode="&#xf0fc;" horiz-adv-x="1664" d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" />
-<glyph unicode="&#xf0fd;" d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf0fe;" d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf100;" horiz-adv-x="1024" d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" />
-<glyph unicode="&#xf101;" horiz-adv-x="1024" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23 l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-<glyph unicode="&#xf102;" horiz-adv-x="1152" d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393 q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-<glyph unicode="&#xf103;" horiz-adv-x="1152" d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-<glyph unicode="&#xf104;" horiz-adv-x="640" d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-<glyph unicode="&#xf105;" horiz-adv-x="640" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-<glyph unicode="&#xf106;" horiz-adv-x="1152" d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-<glyph unicode="&#xf107;" horiz-adv-x="1152" d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-<glyph unicode="&#xf108;" horiz-adv-x="1920" d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19 t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf109;" horiz-adv-x="1920" d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" />
-<glyph unicode="&#xf10a;" horiz-adv-x="1152" d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832 q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf10b;" horiz-adv-x="768" d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136 q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf10c;" d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf10d;" horiz-adv-x="1664" d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" />
-<glyph unicode="&#xf10e;" horiz-adv-x="1664" d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" />
-<glyph unicode="&#xf110;" horiz-adv-x="1568" d="M496 192q0 -60 -42.5 -102t-101.5 -42q-60 0 -102 42t-42 102t42 102t102 42q59 0 101.5 -42t42.5 -102zM928 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -66 -47 -113t-113 -47t-113 47t-47 113 t47 113t113 47t113 -47t47 -113zM1360 192q0 -46 -33 -79t-79 -33t-79 33t-33 79t33 79t79 33t79 -33t33 -79zM528 1088q0 -73 -51.5 -124.5t-124.5 -51.5t-124.5 51.5t-51.5 124.5t51.5 124.5t124.5 51.5t124.5 -51.5t51.5 -124.5zM992 1280q0 -80 -56 -136t-136 -56 t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1536 640q0 -40 -28 -68t-68 -28t-68 28t-28 68t28 68t68 28t68 -28t28 -68zM1328 1088q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5z" />
-<glyph unicode="&#xf111;" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf112;" horiz-adv-x="1792" d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" />
-<glyph unicode="&#xf113;" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 q0 -87 -27 -168q136 -160 136 -398z" />
-<glyph unicode="&#xf114;" horiz-adv-x="1664" d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
-<glyph unicode="&#xf115;" horiz-adv-x="1920" d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z " />
-<glyph unicode="&#xf116;" horiz-adv-x="1792" />
-<glyph unicode="&#xf117;" horiz-adv-x="1792" />
-<glyph unicode="&#xf118;" d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf119;" d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf11a;" d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf11b;" horiz-adv-x="1920" d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" />
-<glyph unicode="&#xf11c;" horiz-adv-x="1920" d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16 h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16 h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96 q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896 h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" />
-<glyph unicode="&#xf11d;" horiz-adv-x="1792" d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9 h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102 q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
-<glyph unicode="&#xf11e;" horiz-adv-x="1792" d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2 q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266 q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8 q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
-<glyph unicode="&#xf120;" horiz-adv-x="1664" d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9 t9 -23z" />
-<glyph unicode="&#xf121;" horiz-adv-x="1920" d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" />
-<glyph unicode="&#xf122;" horiz-adv-x="1792" d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1 q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" />
-<glyph unicode="&#xf123;" horiz-adv-x="1664" d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5 l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" />
-<glyph unicode="&#xf124;" horiz-adv-x="1408" d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" />
-<glyph unicode="&#xf125;" horiz-adv-x="1664" d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23 v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf126;" horiz-adv-x="1024" d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497 q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" />
-<glyph unicode="&#xf127;" horiz-adv-x="1664" d="M439 265l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320 q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18 l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9 t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
-<glyph unicode="&#xf128;" horiz-adv-x="1024" d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5 t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" />
-<glyph unicode="&#xf129;" horiz-adv-x="640" d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192 q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf12a;" horiz-adv-x="640" d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" />
-<glyph unicode="&#xf12b;" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1534 846v-206h-514l-3 27 q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5t-65.5 -51.5t-30.5 -63h232v80 h126z" />
-<glyph unicode="&#xf12c;" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1536 -50v-206h-514l-4 27 q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126z" />
-<glyph unicode="&#xf12d;" horiz-adv-x="1920" d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" />
-<glyph unicode="&#xf12e;" horiz-adv-x="1664" d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5 t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" />
-<glyph unicode="&#xf130;" horiz-adv-x="1152" d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5 t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" />
-<glyph unicode="&#xf131;" horiz-adv-x="1408" d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128 q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23 t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
-<glyph unicode="&#xf132;" horiz-adv-x="1280" d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150 t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf133;" horiz-adv-x="1664" d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf134;" horiz-adv-x="1408" d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" />
-<glyph unicode="&#xf135;" horiz-adv-x="1664" d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" />
-<glyph unicode="&#xf136;" horiz-adv-x="1792" d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" />
-<glyph unicode="&#xf137;" d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf138;" d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf139;" d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf13a;" d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf13b;" horiz-adv-x="1408" d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" />
-<glyph unicode="&#xf13c;" horiz-adv-x="1792" d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" />
-<glyph unicode="&#xf13d;" horiz-adv-x="1792" d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-13 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352 q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19 t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf13e;" horiz-adv-x="1152" d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181 v-320h736z" />
-<glyph unicode="&#xf140;" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150 t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf141;" horiz-adv-x="1408" d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf142;" horiz-adv-x="384" d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf143;" d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10 t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf144;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56 q16 -8 32 -8q17 0 32 9z" />
-<glyph unicode="&#xf145;" horiz-adv-x="1792" d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136 t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" />
-<glyph unicode="&#xf146;" d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" />
-<glyph unicode="&#xf147;" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5 t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf148;" horiz-adv-x="1024" d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" />
-<glyph unicode="&#xf149;" horiz-adv-x="1024" d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" />
-<glyph unicode="&#xf14a;" d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5 t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf14b;" d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf14c;" d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf14d;" d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5 t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf14e;" d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf150;" d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf151;" d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf152;" d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf153;" horiz-adv-x="1024" d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9 t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26 l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" />
-<glyph unicode="&#xf154;" horiz-adv-x="1024" d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7 q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" />
-<glyph unicode="&#xf155;" horiz-adv-x="1024" d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 t53 -63.5t31.5 -76.5t13 -94z" />
-<glyph unicode="&#xf156;" horiz-adv-x="898" d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf157;" horiz-adv-x="1027" d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" />
-<glyph unicode="&#xf158;" horiz-adv-x="1280" d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128 q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" />
-<glyph unicode="&#xf159;" horiz-adv-x="1792" d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf15a;" horiz-adv-x="1280" d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" />
-<glyph unicode="&#xf15b;" d="M1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472zM896 992q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544z" />
-<glyph unicode="&#xf15c;" d="M1468 1060q14 -14 28 -36h-472v472q22 -14 36 -28zM992 896h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28zM1152 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704 q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23z" />
-<glyph unicode="&#xf15d;" horiz-adv-x="1664" d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23 v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162 l230 -662h70z" />
-<glyph unicode="&#xf15e;" horiz-adv-x="1664" d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150 v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248 v119h121z" />
-<glyph unicode="&#xf160;" horiz-adv-x="1792" d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832 q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf161;" horiz-adv-x="1792" d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192 q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf162;" d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23 zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5 t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" />
-<glyph unicode="&#xf163;" d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9 t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13 q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" />
-<glyph unicode="&#xf164;" horiz-adv-x="1664" d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76 q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5 t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" />
-<glyph unicode="&#xf165;" horiz-adv-x="1664" d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135 t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121 t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" />
-<glyph unicode="&#xf166;" d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15 q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38 q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5 q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78l24 -69t23 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38 q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf167;" d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51 q-28 38 -28 118v175q0 80 28 117q38 51 105 51q69 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" />
-<glyph unicode="&#xf168;" horiz-adv-x="1408" d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942 q25 45 64 45h241q22 0 31 -15z" />
-<glyph unicode="&#xf169;" d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1 l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf16a;" horiz-adv-x="1792" d="M1280 640q0 37 -30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54zM1792 640q0 -96 -1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58t-69.5 123 q-14 65 -21.5 147.5t-8.5 136.5t-1 150t1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150z" />
-<glyph unicode="&#xf16b;" horiz-adv-x="1792" d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" />
-<glyph unicode="&#xf16c;" horiz-adv-x="1408" d="M928 135v-151l-707 -1v151zM1169 481v-701l-1 -35v-1h-1132l-35 1h-1v736h121v-618h928v618h120zM241 393l704 -65l-13 -150l-705 65zM309 709l683 -183l-39 -146l-683 183zM472 1058l609 -360l-77 -130l-609 360zM832 1389l398 -585l-124 -85l-399 584zM1285 1536 l121 -697l-149 -26l-121 697z" />
-<glyph unicode="&#xf16d;" d="M1362 110v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5zM1078 643q0 124 -90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5 t90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5zM1362 1003v165q0 28 -20 48.5t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165q0 -29 20 -49t49 -20h174q29 0 49 20t20 49zM1536 1211v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139v1142q0 81 58 139 t139 58h1142q81 0 139 -58t58 -139z" />
-<glyph unicode="&#xf16e;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" />
-<glyph unicode="&#xf170;" d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf171;" horiz-adv-x="1408" d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18 t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5 t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" />
-<glyph unicode="&#xf172;" d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5 t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf173;" horiz-adv-x="1024" d="M944 207l80 -237q-23 -35 -111 -66t-177 -32q-104 -2 -190.5 26t-142.5 74t-95 106t-55.5 120t-16.5 118v544h-168v215q72 26 129 69.5t91 90t58 102t34 99t15 88.5q1 5 4.5 8.5t7.5 3.5h244v-424h333v-252h-334v-518q0 -30 6.5 -56t22.5 -52.5t49.5 -41.5t81.5 -14 q78 2 134 29z" />
-<glyph unicode="&#xf174;" d="M1136 75l-62 183q-44 -22 -103 -22q-36 -1 -62 10.5t-38.5 31.5t-17.5 40.5t-5 43.5v398h257v194h-256v326h-188q-8 0 -9 -10q-5 -44 -17.5 -87t-39 -95t-77 -95t-118.5 -68v-165h130v-418q0 -57 21.5 -115t65 -111t121 -85.5t176.5 -30.5q69 1 136.5 25t85.5 50z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf175;" horiz-adv-x="768" d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" />
-<glyph unicode="&#xf176;" horiz-adv-x="768" d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" />
-<glyph unicode="&#xf177;" horiz-adv-x="1792" d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf178;" horiz-adv-x="1792" d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" />
-<glyph unicode="&#xf179;" horiz-adv-x="1408" d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65 q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" />
-<glyph unicode="&#xf17a;" horiz-adv-x="1664" d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" />
-<glyph unicode="&#xf17b;" horiz-adv-x="1408" d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30 t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5 h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" />
-<glyph unicode="&#xf17c;" d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18l-4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92 q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152 q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-14 -1 -7 -7l4 -2 q14 -4 18 -31q0 -3 8 2zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5 t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43q-19 4 -51 9.5 t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49t-14 -48 q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54q110 143 124 195 q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5t-40.5 -33.5t-61 -14 q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5t15.5 47.5q1 -31 8 -56.5 t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" />
-<glyph unicode="&#xf17d;" d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81 t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19 q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6 t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf17e;" d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5 t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5 q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80 q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" />
-<glyph unicode="&#xf180;" horiz-adv-x="1280" d="M1000 1102l37 194q5 23 -9 40t-35 17h-712q-23 0 -38.5 -17t-15.5 -37v-1101q0 -7 6 -1l291 352q23 26 38 33.5t48 7.5h239q22 0 37 14.5t18 29.5q24 130 37 191q4 21 -11.5 40t-36.5 19h-294q-29 0 -48 19t-19 48v42q0 29 19 47.5t48 18.5h346q18 0 35 13.5t20 29.5z M1227 1324q-15 -73 -53.5 -266.5t-69.5 -350t-35 -173.5q-6 -22 -9 -32.5t-14 -32.5t-24.5 -33t-38.5 -21t-58 -10h-271q-13 0 -22 -10q-8 -9 -426 -494q-22 -25 -58.5 -28.5t-48.5 5.5q-55 22 -55 98v1410q0 55 38 102.5t120 47.5h888q95 0 127 -53t10 -159zM1227 1324 l-158 -790q4 17 35 173.5t69.5 350t53.5 266.5z" />
-<glyph unicode="&#xf181;" d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408 q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf182;" horiz-adv-x="1280" d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43 q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-<glyph unicode="&#xf183;" horiz-adv-x="1024" d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-<glyph unicode="&#xf184;" d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf185;" horiz-adv-x="1792" d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4 l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94 q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" />
-<glyph unicode="&#xf186;" d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" />
-<glyph unicode="&#xf187;" horiz-adv-x="1792" d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536 q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf188;" horiz-adv-x="1664" d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" />
-<glyph unicode="&#xf189;" horiz-adv-x="1920" d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q17 19 38 30q53 26 239 24 q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 q39 5 64 -2.5t31 -16.5z" />
-<glyph unicode="&#xf18a;" horiz-adv-x="1792" d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" />
-<glyph unicode="&#xf18b;" d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495 q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" />
-<glyph unicode="&#xf18c;" horiz-adv-x="1408" d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5 t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56 t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -5 1 -50.5t-1 -71.5q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5 t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" />
-<glyph unicode="&#xf18d;" horiz-adv-x="1280" d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z " />
-<glyph unicode="&#xf18e;" d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf190;" d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf191;" d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf192;" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf193;" horiz-adv-x="1664" d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128 q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 16 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" />
-<glyph unicode="&#xf194;" d="M1254 899q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69 t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237 q104 139 172.5 292.5t82.5 226.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf195;" horiz-adv-x="1152" d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160 q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf196;" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf197;" horiz-adv-x="2176" d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40 t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29 q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" />
-<glyph unicode="&#xf198;" horiz-adv-x="1664" d="M1519 760q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72l-55 163l-153 -53q-29 -9 -50 -9 q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102 t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8zM725 498l310 105l-105 315l-310 -107z" />
-<glyph unicode="&#xf199;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM1280 352v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99q-98 -69 -164 -69v0v0q-66 0 -164 69 q-46 32 -141.5 92.5t-142.5 92.5q-12 8 -33 27t-31 27v-436q0 -40 28 -68t68 -28h832q40 0 68 28t28 68zM1280 925q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13 t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5z" />
-<glyph unicode="&#xf19a;" horiz-adv-x="1792" d="M127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM1415 679q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15t-1.5 -18.5t9 -16.5 t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21 t14.5 -24t14 -23q63 -107 63 -212zM909 573l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1570 1009q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5l235 678q59 169 59 276q0 42 -6 79zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286 t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 -215q173 0 331.5 68t273 182.5t182.5 273t68 331.5t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5t68 -331.5t182.5 -273 t273 -182.5t331.5 -68z" />
-<glyph unicode="&#xf19b;" horiz-adv-x="1792" d="M1086 1536v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360zM1755 954l37 -390l-525 114l147 83q-119 70 -280 99v172q277 -33 481 -157z" />
-<glyph unicode="&#xf19c;" horiz-adv-x="2048" d="M960 1536l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664v64q0 26 20.5 45t48.5 19h59v768zM1851 -64 q28 0 48.5 -19t20.5 -45v-128h-1920v128q0 26 20.5 45t48.5 19h1782z" />
-<glyph unicode="&#xf19d;" horiz-adv-x="2304" d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433 q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" />
-<glyph unicode="&#xf19e;" d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q43 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0 q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" />
-<glyph unicode="&#xf1a0;" horiz-adv-x="1280" d="M981 197q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -49 2q-53 0 -104.5 -7t-107 -25t-97 -46t-68.5 -74.5t-27 -105.5q0 -56 23.5 -102t61 -75.5t87 -50t100 -29t101.5 -8.5q58 0 111.5 13t99 39t73 73t27.5 109zM864 1055 q0 59 -17 125.5t-48 129t-84 103.5t-117 41q-42 0 -82.5 -19.5t-66.5 -52.5q-46 -59 -46 -160q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q37 0 77.5 16.5t65.5 43.5q53 56 53 159zM752 1536h417l-137 -88h-132q75 -63 113 -133t38 -160q0 -72 -24.5 -129.5 t-59.5 -93t-69.5 -65t-59 -61.5t-24.5 -66q0 -36 32 -70.5t77 -68t90.5 -73.5t77.5 -104t32 -142q0 -91 -49 -173q-71 -122 -209.5 -179.5t-298.5 -57.5q-132 0 -246.5 41.5t-172.5 137.5q-36 59 -36 131q0 81 44.5 150t118.5 115q131 82 404 100q-32 41 -47.5 73.5 t-15.5 73.5q0 40 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q76 66 182 98t218 32z" />
-<glyph unicode="&#xf1a1;" horiz-adv-x="1984" d="M831 572q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96q0 57 41.5 98t97.5 41t96.5 -41t40.5 -98zM1292 711q56 0 96.5 -41t40.5 -98q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96q0 57 41.5 98t97.5 41zM1984 722q0 -62 -31 -114t-83 -82q5 -33 5 -61 q0 -121 -68.5 -230.5t-197.5 -193.5q-125 -82 -285.5 -125.5t-335.5 -43.5q-176 0 -336.5 43.5t-284.5 125.5q-129 84 -197.5 193t-68.5 231q0 29 5 66q-48 31 -77 81.5t-29 109.5q0 94 66 160t160 66q83 0 148 -55q248 158 592 164l134 423q4 14 17.5 21.5t28.5 4.5 l347 -82q22 50 68.5 81t102.5 31q77 0 131.5 -54.5t54.5 -131.5t-54.5 -132t-131.5 -55q-76 0 -130.5 54t-55.5 131l-315 74l-116 -366q327 -14 560 -166q64 58 151 58q94 0 160 -66t66 -160zM1664 1459q-45 0 -77 -32t-32 -77t32 -77t77 -32t77 32t32 77t-32 77t-77 32z M77 722q0 -67 51 -111q49 131 180 235q-36 25 -82 25q-62 0 -105.5 -43.5t-43.5 -105.5zM1567 105q112 73 171.5 166t59.5 194t-59.5 193.5t-171.5 165.5q-116 75 -265.5 115.5t-313.5 40.5t-313.5 -40.5t-265.5 -115.5q-112 -73 -171.5 -165.5t-59.5 -193.5t59.5 -194 t171.5 -166q116 -75 265.5 -115.5t313.5 -40.5t313.5 40.5t265.5 115.5zM1850 605q57 46 57 117q0 62 -43.5 105.5t-105.5 43.5q-49 0 -86 -28q131 -105 178 -238zM1258 237q11 11 27 11t27 -11t11 -27.5t-11 -27.5q-99 -99 -319 -99h-2q-220 0 -319 99q-11 11 -11 27.5 t11 27.5t27 11t27 -11q77 -77 265 -77h2q188 0 265 77z" />
-<glyph unicode="&#xf1a2;" d="M950 393q7 7 17.5 7t17.5 -7t7 -18t-7 -18q-65 -64 -208 -64h-1h-1q-143 0 -207 64q-8 7 -8 18t8 18q7 7 17.5 7t17.5 -7q49 -51 172 -51h1h1q122 0 173 51zM671 613q0 -37 -26 -64t-63 -27t-63 27t-26 64t26 63t63 26t63 -26t26 -63zM1214 1049q-29 0 -50 21t-21 50 q0 30 21 51t50 21q30 0 51 -21t21 -51q0 -29 -21 -50t-51 -21zM1216 1408q132 0 226 -94t94 -227v-894q0 -133 -94 -227t-226 -94h-896q-132 0 -226 94t-94 227v894q0 133 94 227t226 94h896zM1321 596q35 14 57 45.5t22 70.5q0 51 -36 87.5t-87 36.5q-60 0 -98 -48 q-151 107 -375 115l83 265l206 -49q1 -50 36.5 -85t84.5 -35q50 0 86 35.5t36 85.5t-36 86t-86 36q-36 0 -66 -20.5t-45 -53.5l-227 54q-9 2 -17.5 -2.5t-11.5 -14.5l-95 -302q-224 -4 -381 -113q-36 43 -93 43q-51 0 -87 -36.5t-36 -87.5q0 -37 19.5 -67.5t52.5 -45.5 q-7 -25 -7 -54q0 -98 74 -181.5t201.5 -132t278.5 -48.5q150 0 277.5 48.5t201.5 132t74 181.5q0 27 -6 54zM971 702q37 0 63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64t26 63t63 26z" />
-<glyph unicode="&#xf1a3;" d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150 v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103 t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf1a4;" horiz-adv-x="1920" d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328 v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" />
-<glyph unicode="&#xf1a5;" d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" />
-<glyph unicode="&#xf1a6;" horiz-adv-x="2048" d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968v-697h205v697h-205zM614 1254v-204h205v204h-205zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123 v-369h123z" />
-<glyph unicode="&#xf1a7;" d="M1046 516q0 -64 -38 -109t-91 -45q-43 0 -70 15v277q28 17 70 17q53 0 91 -45.5t38 -109.5zM703 944q0 -64 -38 -109.5t-91 -45.5q-43 0 -70 15v277q28 17 70 17q53 0 91 -45t38 -109zM1265 513q0 134 -88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101 v-636l211 41v206q51 -19 117 -19q125 0 213 95t88 229zM922 940q0 134 -88.5 229t-213.5 95q-74 0 -141 -36h-186v-840l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf1a8;" horiz-adv-x="2038" d="M1222 607q75 3 143.5 -20.5t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14 q6 -5 28 -23.5t25.5 -22t19 -18t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24 q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33 q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5 t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5zM1282 842q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43 q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5 t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM822 568l48 12l109 -177l-73 -48zM1323 51q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13 t-54 -9.5t-53.5 -7.5t-32 -4.5l-7 43q21 2 60.5 8.5t72 10t60.5 3.5h14zM866 679l-96 -20l-6 17q10 1 32.5 7t34.5 6q19 0 35 -10zM1061 45h31l10 -83l-41 -12v95zM1950 1535v1v-1zM1950 1535l-1 -5l-2 -2l1 3zM1950 1535l1 1z" />
-<glyph unicode="&#xf1a9;" d="M1167 -50q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16t7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29zM1128 65q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10 q-29 -12 -78 -56q-26 -24 -12 -44q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34zM1483 346q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14 q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14 t55.5 63q28 41 42.5 101t14.5 106zM1536 506q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44 q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5t19.5 -177.5z" />
-<glyph unicode="&#xf1aa;" d="M1070 463l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5t-60 145.5q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160z M729 1145l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5q-70 15 -115 71t-45 129q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5 t149.5 -87.5zM1536 78q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5 q76 -11 126.5 -68.5t50.5 -134.5zM1534 1202q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152l-160 -160l-152 152l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126 t135.5 51q85 0 145 -60.5t60 -145.5z" />
-<glyph unicode="&#xf1ab;" d="M654 458q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110q-4 -2 -19.5 -4t-18.5 0q6 4 82 92q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5 q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28 q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5zM449 944q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032l-694 -233v-1031z M1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11 q73 -37 159.5 -61.5t157.5 -24.5q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5zM1536 1050v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3v1078q3 9 4 10q5 6 20 11q106 35 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5 q20 0 20 -21v-418z" />
-<glyph unicode="&#xf1ac;" horiz-adv-x="1792" d="M288 1152q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h128zM1664 989q58 -34 93 -93t35 -128v-768q0 -106 -75 -181t-181 -75h-864q-66 0 -113 47t-47 113v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48 l152 -152q28 -28 48 -76t20 -88v-163zM928 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 512v128q0 14 -9 23 t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128 q14 0 23 9t9 23zM1184 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 256v128q0 14 -9 23t-23 9h-128 q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1536 896v256h-160q-40 0 -68 28t-28 68v160h-640v-512h896z" />
-<glyph unicode="&#xf1ad;" d="M1344 1536q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280zM512 1248v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 992v-64q0 -14 9 -23t23 -9h64q14 0 23 9 t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 736v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 480v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 160v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 q14 0 23 9t9 23zM384 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 -96v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9 t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM896 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 928v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 160v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23z" />
-<glyph unicode="&#xf1ae;" horiz-adv-x="1280" d="M1188 988l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68t28 68t68 28t68 -28l228 -228h368l228 228q28 28 68 28t68 -28t28 -68t-28 -68zM864 1152q0 -93 -65.5 -158.5 t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-<glyph unicode="&#xf1b0;" horiz-adv-x="1664" d="M780 1064q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5zM438 581q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152q0 80 42 139.5t119 59.5 q76 0 141.5 -55.5t100.5 -134t35 -152.5zM832 608q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146q0 86 56 191.5t139.5 192.5t187.5 146t193 59zM1071 819 q-61 0 -105 39t-63 92.5t-19 113.5q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5zM1503 923q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5q-77 0 -119 59t-42 139q0 74 35 152.5 t100.5 134t141.5 55.5z" />
-<glyph unicode="&#xf1b1;" horiz-adv-x="768" d="M704 1008q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5z" />
-<glyph unicode="&#xf1b2;" horiz-adv-x="1792" d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73z " />
-<glyph unicode="&#xf1b3;" horiz-adv-x="2304" d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416q0 -36 -19 -67 t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-5 2 -7 4q-2 -2 -7 -4l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70 v-400l434 -186q36 -16 57 -48t21 -70z" />
-<glyph unicode="&#xf1b4;" horiz-adv-x="2048" d="M1848 1197h-511v-124h511v124zM1596 771q-90 0 -146 -52.5t-62 -142.5h408q-18 195 -200 195zM1612 186q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658 q0 -111 57.5 -171.5t166.5 -60.5zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5t45.5 113.5q0 144 -190 144h-260v-294zM0 1282h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204 q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611v1260z" />
-<glyph unicode="&#xf1b5;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM499 1041h-371v-787h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5 t-56.5 60.5t-79 29.5t-97 8.5zM477 723h-176v184h163q119 0 119 -90q0 -94 -106 -94zM486 388h-185v217h189q124 0 124 -113q0 -104 -128 -104zM1136 356q-68 0 -104 38t-36 107h411q1 10 1 30q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216q0 -135 79 -217 t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20zM1126 722q113 0 124 -122h-254q4 56 39 89t91 33zM964 988h319v-77h-319v77z" />
-<glyph unicode="&#xf1b6;" horiz-adv-x="1792" d="M1582 954q0 -101 -71.5 -172.5t-172.5 -71.5t-172.5 71.5t-71.5 172.5t71.5 172.5t172.5 71.5t172.5 -71.5t71.5 -172.5zM812 212q0 104 -73 177t-177 73q-27 0 -54 -6l104 -42q77 -31 109.5 -106.5t1.5 -151.5q-31 -77 -107 -109t-152 -1q-21 8 -62 24.5t-61 24.5 q32 -60 91 -96.5t130 -36.5q104 0 177 73t73 177zM1642 953q0 126 -89.5 215.5t-215.5 89.5q-127 0 -216.5 -89.5t-89.5 -215.5q0 -127 89.5 -216t216.5 -89q126 0 215.5 89t89.5 216zM1792 953q0 -189 -133.5 -322t-321.5 -133l-437 -319q-12 -129 -109 -218t-229 -89 q-121 0 -214 76t-118 192l-230 92v429l389 -157q79 48 173 48q13 0 35 -2l284 407q2 187 135.5 319t320.5 132q188 0 321.5 -133.5t133.5 -321.5z" />
-<glyph unicode="&#xf1b7;" d="M1242 889q0 80 -57 136.5t-137 56.5t-136.5 -57t-56.5 -136q0 -80 56.5 -136.5t136.5 -56.5t137 56.5t57 136.5zM632 301q0 -83 -58 -140.5t-140 -57.5q-56 0 -103 29t-72 77q52 -20 98 -40q60 -24 120 1.5t85 86.5q24 60 -1.5 120t-86.5 84l-82 33q22 5 42 5 q82 0 140 -57.5t58 -140.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v153l172 -69q20 -92 93.5 -152t168.5 -60q104 0 181 70t87 173l345 252q150 0 255.5 105.5t105.5 254.5q0 150 -105.5 255.5t-255.5 105.5 q-148 0 -253 -104.5t-107 -252.5l-225 -322q-9 1 -28 1q-75 0 -137 -37l-297 119v468q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5zM1289 887q0 -100 -71 -170.5t-171 -70.5t-170.5 70.5t-70.5 170.5t70.5 171t170.5 71q101 0 171.5 -70.5t70.5 -171.5z " />
-<glyph unicode="&#xf1b8;" horiz-adv-x="1792" d="M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188 l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5 t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1 q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z" />
-<glyph unicode="&#xf1b9;" horiz-adv-x="2048" d="M480 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM516 768h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5zM1888 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM2048 544v-384 q0 -14 -9 -23t-23 -9h-96v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-1024v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h768q98 0 179 -63.5t104 -157.5 l105 -419h28q93 0 158.5 -65.5t65.5 -158.5z" />
-<glyph unicode="&#xf1ba;" horiz-adv-x="2048" d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5 t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" />
-<glyph unicode="&#xf1bb;" d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384 q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" />
-<glyph unicode="&#xf1bc;" d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64 q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37 q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf1bd;" d="M1397 1408q58 0 98.5 -40.5t40.5 -98.5v-1258q0 -58 -40.5 -98.5t-98.5 -40.5h-1258q-58 0 -98.5 40.5t-40.5 98.5v1258q0 58 40.5 98.5t98.5 40.5h1258zM1465 11v1258q0 28 -20 48t-48 20h-1258q-28 0 -48 -20t-20 -48v-1258q0 -28 20 -48t48 -20h1258q28 0 48 20t20 48 zM694 749l188 -387l533 145v-496q0 -7 -5.5 -12.5t-12.5 -5.5h-1258q-7 0 -12.5 5.5t-5.5 12.5v141l711 195l-212 439q4 1 12 2.5t12 1.5q170 32 303.5 21.5t221 -46t143.5 -94.5q27 -28 -25 -42q-64 -16 -256 -62l-97 198q-111 7 -240 -16zM1397 1287q7 0 12.5 -5.5 t5.5 -12.5v-428q-85 30 -188 52q-294 64 -645 12l-18 -3l-65 134h-233l85 -190q-132 -51 -230 -137v560q0 7 5.5 12.5t12.5 5.5h1258zM286 387q-14 -3 -26 4.5t-14 21.5q-24 203 166 305l129 -270z" />
-<glyph unicode="&#xf1be;" horiz-adv-x="2304" d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11 q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245 q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785 l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242 q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236q0 -11 -8 -19 t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786q-13 2 -22 11t-9 22v899 q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" />
-<glyph unicode="&#xf1c0;" d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127 t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 t-103 128v128q0 69 103 128t280 93.5t385 34.5z" />
-<glyph unicode="&#xf1c1;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197 q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8 q-1 1 -1 2t-0.5 1.5t-0.5 1.5q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" />
-<glyph unicode="&#xf1c2;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M233 768v-107h70l164 -661h159l128 485q7 20 10 46q2 16 2 24h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4l-3 21q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5t-3.5 -21.5l-4 -21h-4l-2 21 q-2 26 -7 46l-99 438h90v107h-300z" />
-<glyph unicode="&#xf1c3;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M429 106v-106h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107 h-290v-107h68l189 -272l-194 -283h-68z" />
-<glyph unicode="&#xf1c4;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M416 106v-106h327v106h-93v167h137q76 0 118 15q67 23 106.5 87t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92zM769 386h-119v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15z" />
-<glyph unicode="&#xf1c5;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z" />
-<glyph unicode="&#xf1c6;" d="M640 1152v128h-128v-128h128zM768 1024v128h-128v-128h128zM640 896v128h-128v-128h128zM768 768v128h-128v-128h128zM1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400 v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536h1280zM781 593l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5q0 25 8 52q21 63 120 396v128h128v-128h79 q22 0 39 -13t23 -34zM640 128q53 0 90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45t37.5 -45t90.5 -19z" />
-<glyph unicode="&#xf1c7;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M620 686q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h131l166 167q16 15 35 7zM1037 -3q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5 q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5t23.5 -42.5q18 -15 40 -15zM826 145q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5t20 -44.5q20 -17 44 -17z" />
-<glyph unicode="&#xf1c8;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M768 768q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h384zM1260 766q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9l-265 266v90l265 266q9 9 23 9q4 0 12 -2z" />
-<glyph unicode="&#xf1c9;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M480 768q8 11 21 12.5t24 -6.5l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5l-226 301q-14 19 0 38zM1282 467q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21t6.5 24l182 243 l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5zM662 6q-13 2 -20.5 13t-5.5 24l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5z" />
-<glyph unicode="&#xf1ca;" d="M1497 709v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406 q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z" />
-<glyph unicode="&#xf1cb;" horiz-adv-x="1792" d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546 q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64z" />
-<glyph unicode="&#xf1cc;" horiz-adv-x="2048" d="M1800 764q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94 q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55 t121.5 -21q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97q14 -16 29.5 -34t34.5 -40t29 -34q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5 t-85 -189.5z" />
-<glyph unicode="&#xf1cd;" horiz-adv-x="1792" d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 1408q-190 0 -361 -90l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90zM218 279l194 194 q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361t90 -361zM896 -128q190 0 361 90l-194 194q-82 -28 -167 -28t-167 28l-194 -194q171 -90 361 -90zM896 256q159 0 271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5 t271.5 -112.5zM1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" />
-<glyph unicode="&#xf1ce;" horiz-adv-x="1792" d="M1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348q0 222 101 414.5t276.5 317t390.5 155.5v-260q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 q0 230 -145.5 406t-366.5 221v260q215 -31 390.5 -155.5t276.5 -317t101 -414.5z" />
-<glyph unicode="&#xf1d0;" horiz-adv-x="1792" d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41 t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170 t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136 q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" />
-<glyph unicode="&#xf1d1;" horiz-adv-x="1792" d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251 l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162 q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33 q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5 t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71 t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-<glyph unicode="&#xf1d2;" d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85 q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392 q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24zM924 1072 q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf1d3;" horiz-adv-x="1792" d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58 q0 -31 22.5 -51.5t58 -32t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47 q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171 v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" />
-<glyph unicode="&#xf1d4;" d="M825 547l343 588h-150q-21 -39 -63.5 -118.5t-68 -128.5t-59.5 -118.5t-60 -128.5h-3q-21 48 -44.5 97t-52 105.5t-46.5 92t-54 104.5t-49 95h-150l323 -589v-435h134v436zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf1d5;" horiz-adv-x="1280" d="M842 964q0 -80 -57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5 t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153 t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" />
-<glyph unicode="&#xf1d6;" horiz-adv-x="1792" d="M270 730q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5t3.5 -5t2 -3.5 q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9t-98 20 t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20q-18 -41 -54.5 -74.5 t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" />
-<glyph unicode="&#xf1d7;" horiz-adv-x="2048" d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25 q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5 q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109 q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" />
-<glyph unicode="&#xf1d8;" horiz-adv-x="1792" d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11z" />
-<glyph unicode="&#xf1d9;" horiz-adv-x="1792" d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55q-3 39 32 59l1664 960q35 21 68 -2zM1422 26l221 1323l-1434 -827l336 -137 l863 639l-478 -797z" />
-<glyph unicode="&#xf1da;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23 t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf1db;" d="M768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf1dc;" horiz-adv-x="1792" d="M1682 -128q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5t45 -15 t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18q-15 10 -45 12t-53 2 t-41 14t-18 45q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160 q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5 q0 -26 -12 -48t-36 -22z" />
-<glyph unicode="&#xf1dd;" horiz-adv-x="1280" d="M1278 1347v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179 q-64 117 -64 259q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43z" />
-<glyph unicode="&#xf1de;" d="M352 128v-128h-352v128h352zM704 256q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280q26 0 45 -19t19 -45v-256 q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1216 768q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" />
-<glyph unicode="&#xf1e0;" d="M1216 512q133 0 226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5 t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86z" />
-<glyph unicode="&#xf1e1;" d="M1280 341q0 88 -62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5t62.5 -150.5 t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5t150.5 62.5t62.5 150.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf1e2;" horiz-adv-x="1792" d="M571 947q-10 25 -34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49t35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49zM1513 1303l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5 t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68zM1521 1359q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23t9 23q10 9 23 9t23 -9l90 -91 q10 -9 10 -22.5t-10 -22.5zM1751 1129q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5t10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23zM1792 1312q0 -14 -9 -23t-23 -9h-96q-14 0 -23 9t-9 23t9 23t23 9h96q14 0 23 -9t9 -23zM1600 1504v-96q0 -14 -9 -23t-23 -9 t-23 9t-9 23v96q0 14 9 23t23 9t23 -9t9 -23zM1751 1449l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5t10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
-<glyph unicode="&#xf1e3;" horiz-adv-x="1792" d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM1515 186q149 203 149 454v3l-102 -89l-240 224l63 323 l134 -12q-150 206 -389 282l53 -124l-287 -159l-287 159l53 124q-239 -76 -389 -282l135 12l62 -323l-240 -224l-102 89v-3q0 -251 149 -454l30 132l326 -40l139 -298l-116 -69q117 -39 240 -39t240 39l-116 69l139 298l326 40z" />
-<glyph unicode="&#xf1e4;" horiz-adv-x="1792" d="M448 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM256 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM832 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM66 768q-28 0 -47 19t-19 46v129h514v-129q0 -27 -19 -46t-46 -19h-383zM1216 224v-192q0 -14 -9 -23t-23 -9h-192 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1600 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23 zM1408 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1016v-13h-514v10q0 104 -382 102q-382 -1 -382 -102v-10h-514v13q0 17 8.5 43t34 64t65.5 75.5t110.5 76t160 67.5t224 47.5t293.5 18.5t293 -18.5t224 -47.5 t160.5 -67.5t110.5 -76t65.5 -75.5t34 -64t8.5 -43zM1792 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 962v-129q0 -27 -19 -46t-46 -19h-384q-27 0 -46 19t-19 46v129h514z" />
-<glyph unicode="&#xf1e5;" horiz-adv-x="1792" d="M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf1e6;" horiz-adv-x="1792" d="M1755 1083q37 -37 37 -90t-37 -91l-401 -400l150 -150l-160 -160q-163 -163 -389.5 -186.5t-411.5 100.5l-362 -362h-181v181l362 362q-124 185 -100.5 411.5t186.5 389.5l160 160l150 -150l400 401q38 37 91 37t90 -37t37 -90.5t-37 -90.5l-400 -401l234 -234l401 400 q38 37 91 37t90 -37z" />
-<glyph unicode="&#xf1e7;" horiz-adv-x="1792" d="M873 796q0 -83 -63.5 -142.5t-152.5 -59.5t-152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59t152.5 -59t63.5 -143zM1375 796q0 -83 -63 -142.5t-153 -59.5q-89 0 -152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59q90 0 153 -59t63 -143zM1600 616v667q0 87 -32 123.5 t-111 36.5h-1112q-83 0 -112.5 -34t-29.5 -126v-673q43 -23 88.5 -40t81 -28t81 -18.5t71 -11t70 -4t58.5 -0.5t56.5 2t44.5 2q68 1 95 -27q6 -6 10 -9q26 -25 61 -51q7 91 118 87q5 0 36.5 -1.5t43 -2t45.5 -1t53 1t54.5 4.5t61 8.5t62 13.5t67 19.5t67.5 27t72 34.5z M1763 621q-121 -149 -372 -252q84 -285 -23 -465q-66 -113 -183 -148q-104 -32 -182 15q-86 51 -82 164l-1 326v1q-8 2 -24.5 6t-23.5 5l-1 -338q4 -114 -83 -164q-79 -47 -183 -15q-117 36 -182 150q-105 180 -22 463q-251 103 -372 252q-25 37 -4 63t60 -1q3 -2 11 -7 t11 -8v694q0 72 47 123t114 51h1257q67 0 114 -51t47 -123v-694l21 15q39 27 60 1t-4 -63z" />
-<glyph unicode="&#xf1e8;" horiz-adv-x="1792" d="M896 1102v-434h-145v434h145zM1294 1102v-434h-145v434h145zM1294 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1692 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" />
-<glyph unicode="&#xf1e9;" d="M773 217v-127q-1 -292 -6 -305q-12 -32 -51 -40q-54 -9 -181.5 38t-162.5 89q-13 15 -17 36q-1 12 4 26q4 10 34 47t181 216q1 0 60 70q15 19 39.5 24.5t49.5 -3.5q24 -10 37.5 -29t12.5 -42zM624 468q-3 -55 -52 -70l-120 -39q-275 -88 -292 -88q-35 2 -54 36 q-12 25 -17 75q-8 76 1 166.5t30 124.5t56 32q13 0 202 -77q70 -29 115 -47l84 -34q23 -9 35.5 -30.5t11.5 -48.5zM1450 171q-7 -54 -91.5 -161t-135.5 -127q-37 -14 -63 7q-14 10 -184 287l-47 77q-14 21 -11.5 46t19.5 46q35 43 83 26q1 -1 119 -40q203 -66 242 -79.5 t47 -20.5q28 -22 22 -61zM778 803q5 -102 -54 -122q-58 -17 -114 71l-378 598q-8 35 19 62q41 43 207.5 89.5t224.5 31.5q40 -10 49 -45q3 -18 22 -305.5t24 -379.5zM1440 695q3 -39 -26 -59q-15 -10 -329 -86q-67 -15 -91 -23l1 2q-23 -6 -46 4t-37 32q-30 47 0 87 q1 1 75 102q125 171 150 204t34 39q28 19 65 2q48 -23 123 -133.5t81 -167.5v-3z" />
-<glyph unicode="&#xf1ea;" horiz-adv-x="2048" d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19 t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" />
-<glyph unicode="&#xf1eb;" horiz-adv-x="2048" d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121 q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" />
-<glyph unicode="&#xf1ec;" horiz-adv-x="1792" d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5 t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38 h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1ed;" horiz-adv-x="1792" d="M1112 1090q0 159 -237 159h-70q-32 0 -59.5 -21.5t-34.5 -52.5l-63 -276q-2 -5 -2 -16q0 -24 17 -39.5t41 -15.5h53q69 0 128.5 13t112.5 41t83.5 81.5t30.5 126.5zM1716 938q0 -265 -220 -428q-219 -161 -612 -161h-61q-32 0 -59 -21.5t-34 -52.5l-73 -316 q-8 -36 -40.5 -61.5t-69.5 -25.5h-213q-31 0 -53 20t-22 51q0 10 13 65h151q34 0 64 23.5t38 56.5l73 316q8 33 37.5 57t63.5 24h61q390 0 607 160t217 421q0 129 -51 207q183 -92 183 -335zM1533 1123q0 -264 -221 -428q-218 -161 -612 -161h-60q-32 0 -59.5 -22t-34.5 -53 l-73 -315q-8 -36 -40 -61.5t-69 -25.5h-214q-31 0 -52.5 19.5t-21.5 51.5q0 8 2 20l300 1301q8 36 40.5 61.5t69.5 25.5h444q68 0 125 -4t120.5 -15t113.5 -30t96.5 -50.5t77.5 -74t49.5 -103.5t18.5 -136z" />
-<glyph unicode="&#xf1ee;" horiz-adv-x="1792" d="M602 949q19 -61 31 -123.5t17 -141.5t-14 -159t-62 -145q-21 81 -67 157t-95.5 127t-99 90.5t-78.5 57.5t-33 19q-62 34 -81.5 100t14.5 128t101 81.5t129 -14.5q138 -83 238 -177zM927 1236q11 -25 20.5 -46t36.5 -100.5t42.5 -150.5t25.5 -179.5t0 -205.5t-47.5 -209.5 t-105.5 -208.5q-51 -72 -138 -72q-54 0 -98 31q-57 40 -69 109t28 127q60 85 81 195t13 199.5t-32 180.5t-39 128t-22 52q-31 63 -8.5 129.5t85.5 97.5q34 17 75 17q47 0 88.5 -25t63.5 -69zM1248 567q-17 -160 -72 -311q-17 131 -63 246q25 174 -5 361q-27 178 -94 342 q114 -90 212 -211q9 -37 15 -80q26 -179 7 -347zM1520 1440q9 -17 23.5 -49.5t43.5 -117.5t50.5 -178t34 -227.5t5 -269t-47 -300t-112.5 -323.5q-22 -48 -66 -75.5t-95 -27.5q-39 0 -74 16q-67 31 -92.5 100t4.5 136q58 126 90 257.5t37.5 239.5t-3.5 213.5t-26.5 180.5 t-38.5 138.5t-32.5 90t-15.5 32.5q-34 65 -11.5 135.5t87.5 104.5q37 20 81 20q49 0 91.5 -25.5t66.5 -70.5z" />
-<glyph unicode="&#xf1f0;" horiz-adv-x="2304" d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27 q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128 q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1f1;" horiz-adv-x="2304" d="M671 603h-13q-47 0 -47 -32q0 -22 20 -22q17 0 28 15t12 39zM1066 639h62v3q1 4 0.5 6.5t-1 7t-2 8t-4.5 6.5t-7.5 5t-11.5 2q-28 0 -36 -38zM1606 603h-12q-48 0 -48 -32q0 -22 20 -22q17 0 28 15t12 39zM1925 629q0 41 -30 41q-19 0 -31 -20t-12 -51q0 -42 28 -42 q20 0 32.5 20t12.5 52zM480 770h87l-44 -262h-56l32 201l-71 -201h-39l-4 200l-34 -200h-53l44 262h81l2 -163zM733 663q0 -6 -4 -42q-16 -101 -17 -113h-47l1 22q-20 -26 -58 -26q-23 0 -37.5 16t-14.5 42q0 39 26 60.5t73 21.5q14 0 23 -1q0 3 0.5 5.5t1 4.5t0.5 3 q0 20 -36 20q-29 0 -59 -10q0 4 7 48q38 11 67 11q74 0 74 -62zM889 721l-8 -49q-22 3 -41 3q-27 0 -27 -17q0 -8 4.5 -12t21.5 -11q40 -19 40 -60q0 -72 -87 -71q-34 0 -58 6q0 2 7 49q29 -8 51 -8q32 0 32 19q0 7 -4.5 11.5t-21.5 12.5q-43 20 -43 59q0 72 84 72 q30 0 50 -4zM977 721h28l-7 -52h-29q-2 -17 -6.5 -40.5t-7 -38.5t-2.5 -18q0 -16 19 -16q8 0 16 2l-8 -47q-21 -7 -40 -7q-43 0 -45 47q0 12 8 56q3 20 25 146h55zM1180 648q0 -23 -7 -52h-111q-3 -22 10 -33t38 -11q30 0 58 14l-9 -54q-30 -8 -57 -8q-95 0 -95 95 q0 55 27.5 90.5t69.5 35.5q35 0 55.5 -21t20.5 -56zM1319 722q-13 -23 -22 -62q-22 2 -31 -24t-25 -128h-56l3 14q22 130 29 199h51l-3 -33q14 21 25.5 29.5t28.5 4.5zM1506 763l-9 -57q-28 14 -50 14q-31 0 -51 -27.5t-20 -70.5q0 -30 13.5 -47t38.5 -17q21 0 48 13 l-10 -59q-28 -8 -50 -8q-45 0 -71.5 30.5t-26.5 82.5q0 70 35.5 114.5t91.5 44.5q26 0 61 -13zM1668 663q0 -18 -4 -42q-13 -79 -17 -113h-46l1 22q-20 -26 -59 -26q-23 0 -37 16t-14 42q0 39 25.5 60.5t72.5 21.5q15 0 23 -1q2 7 2 13q0 20 -36 20q-29 0 -59 -10q0 4 8 48 q38 11 67 11q73 0 73 -62zM1809 722q-14 -24 -21 -62q-23 2 -31.5 -23t-25.5 -129h-56l3 14q19 104 29 199h52q0 -11 -4 -33q15 21 26.5 29.5t27.5 4.5zM1950 770h56l-43 -262h-53l3 19q-23 -23 -52 -23q-31 0 -49.5 24t-18.5 64q0 53 27.5 92t64.5 39q31 0 53 -29z M2061 640q0 148 -72.5 273t-198 198t-273.5 73q-181 0 -328 -110q127 -116 171 -284h-50q-44 150 -158 253q-114 -103 -158 -253h-50q44 168 171 284q-147 110 -328 110q-148 0 -273.5 -73t-198 -198t-72.5 -273t72.5 -273t198 -198t273.5 -73q181 0 328 110 q-120 111 -165 264h50q46 -138 152 -233q106 95 152 233h50q-45 -153 -165 -264q147 -110 328 -110q148 0 273.5 73t198 198t72.5 273zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1f2;" horiz-adv-x="2304" d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42 q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604 v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569 q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73 t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" />
-<glyph unicode="&#xf1f3;" horiz-adv-x="2304" d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260 l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279 v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040 q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168 q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5 t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21 h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 60t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5 t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" />
-<glyph unicode="&#xf1f4;" horiz-adv-x="2304" d="M322 689h-15q-19 0 -19 18q0 28 19 85q5 15 15 19.5t28 4.5q77 0 77 -49q0 -41 -30.5 -59.5t-74.5 -18.5zM664 528q-47 0 -47 29q0 62 123 62l3 -3q-5 -88 -79 -88zM1438 687h-15q-19 0 -19 19q0 28 19 85q5 15 14.5 19t28.5 4q77 0 77 -49q0 -41 -30.5 -59.5 t-74.5 -18.5zM1780 527q-47 0 -47 30q0 62 123 62l3 -3q-5 -89 -79 -89zM373 894h-128q-8 0 -14.5 -4t-8.5 -7.5t-7 -12.5q-3 -7 -45 -190t-42 -192q0 -7 5.5 -12.5t13.5 -5.5h62q25 0 32.5 34.5l15 69t32.5 34.5q47 0 87.5 7.5t80.5 24.5t63.5 52.5t23.5 84.5 q0 36 -14.5 61t-41 36.5t-53.5 15.5t-62 4zM719 798q-38 0 -74 -6q-2 0 -8.5 -1t-9 -1.5l-7.5 -1.5t-7.5 -2t-6.5 -3t-6.5 -4t-5 -5t-4.5 -7t-4 -9q-9 -29 -9 -39t9 -10q5 0 21.5 5t19.5 6q30 8 58 8q74 0 74 -36q0 -11 -10 -14q-8 -2 -18 -3t-21.5 -1.5t-17.5 -1.5 q-38 -4 -64.5 -10t-56.5 -19.5t-45.5 -39t-15.5 -62.5q0 -38 26 -59.5t64 -21.5q24 0 45.5 6.5t33 13t38.5 23.5q-3 -7 -3 -15t5.5 -13.5t12.5 -5.5h56q1 1 7 3.5t7.5 3.5t5 3.5t5 5.5t2.5 8l45 194q4 13 4 30q0 81 -145 81zM1247 793h-74q-22 0 -39 -23q-5 -7 -29.5 -51 t-46.5 -81.5t-26 -38.5l-5 4q0 77 -27 166q-1 5 -3.5 8.5t-6 6.5t-6.5 5t-8.5 3t-8.5 1.5t-9.5 1t-9 0.5h-10h-8.5q-38 0 -38 -21l1 -5q5 -53 25 -151t25 -143q2 -16 2 -24q0 -19 -30.5 -61.5t-30.5 -58.5q0 -13 40 -13q61 0 76 25l245 415q10 20 10 26q0 9 -8 9zM1489 892 h-129q-18 0 -29 -23q-6 -13 -46.5 -191.5t-40.5 -190.5q0 -20 43 -20h7.5h9h9t9.5 1t8.5 2t8.5 3t6.5 4.5t5.5 6t3 8.5l21 91q2 10 10.5 17t19.5 7q47 0 87.5 7t80.5 24.5t63.5 52.5t23.5 84q0 36 -14.5 61t-41 36.5t-53.5 15.5t-62 4zM1835 798q-26 0 -74 -6 q-38 -6 -48 -16q-7 -8 -11 -19q-8 -24 -8 -39q0 -10 8 -10q1 0 41 12q30 8 58 8q74 0 74 -36q0 -12 -10 -14q-4 -1 -57 -7q-38 -4 -64.5 -10t-56.5 -19.5t-45.5 -39t-15.5 -62.5t26 -58.5t64 -21.5q24 0 45 6t34 13t38 24q-3 -15 -3 -16q0 -5 2 -8.5t6.5 -5.5t8 -3.5 t10.5 -2t9.5 -0.5h9.5h8q42 0 48 25l45 194q3 15 3 31q0 81 -145 81zM2157 889h-55q-25 0 -33 -40q-10 -44 -36.5 -167t-42.5 -190v-5q0 -16 16 -18h1h57q10 0 18.5 6.5t10.5 16.5l83 374h-1l1 5q0 7 -5.5 12.5t-13.5 5.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048 q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1f5;" horiz-adv-x="2304" d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109 q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118 q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151 q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -188q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31 q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1f6;" horiz-adv-x="2048" d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5 l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5 l418 363q10 8 23.5 7t21.5 -11z" />
-<glyph unicode="&#xf1f7;" horiz-adv-x="2048" d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128 q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161 q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" />
-<glyph unicode="&#xf1f8;" horiz-adv-x="1408" d="M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704 q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167 q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf1f9;" d="M1150 462v-109q0 -50 -36.5 -89t-94 -60.5t-118 -32.5t-117.5 -11q-205 0 -342.5 139t-137.5 346q0 203 136 339t339 136q34 0 75.5 -4.5t93 -18t92.5 -34t69 -56.5t28 -81v-109q0 -16 -16 -16h-118q-16 0 -16 16v70q0 43 -65.5 67.5t-137.5 24.5q-140 0 -228.5 -91.5 t-88.5 -237.5q0 -151 91.5 -249.5t233.5 -98.5q68 0 138 24t70 66v70q0 7 4.5 11.5t10.5 4.5h119q6 0 11 -4.5t5 -11.5zM768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf1fa;" d="M972 761q0 108 -53.5 169t-147.5 61q-63 0 -124 -30.5t-110 -84.5t-79.5 -137t-30.5 -180q0 -112 53.5 -173t150.5 -61q96 0 176 66.5t122.5 166t42.5 203.5zM1536 640q0 -111 -37 -197t-98.5 -135t-131.5 -74.5t-145 -27.5q-6 0 -15.5 -0.5t-16.5 -0.5q-95 0 -142 53 q-28 33 -33 83q-52 -66 -131.5 -110t-173.5 -44q-161 0 -249.5 95.5t-88.5 269.5q0 157 66 290t179 210.5t246 77.5q87 0 155 -35.5t106 -99.5l2 19l11 56q1 6 5.5 12t9.5 6h118q5 0 13 -11q5 -5 3 -16l-120 -614q-5 -24 -5 -48q0 -39 12.5 -52t44.5 -13q28 1 57 5.5t73 24 t77 50t57 89.5t24 137q0 292 -174 466t-466 174q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51q228 0 405 144q11 9 24 8t21 -12l41 -49q8 -12 7 -24q-2 -13 -12 -22q-102 -83 -227.5 -128t-258.5 -45q-156 0 -298 61 t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q344 0 556 -212t212 -556z" />
-<glyph unicode="&#xf1fb;" horiz-adv-x="1792" d="M1698 1442q94 -94 94 -226.5t-94 -225.5l-225 -223l104 -104q10 -10 10 -23t-10 -23l-210 -210q-10 -10 -23 -10t-23 10l-105 105l-603 -603q-37 -37 -90 -37h-203l-256 -128l-64 64l128 256v203q0 53 37 90l603 603l-105 105q-10 10 -10 23t10 23l210 210q10 10 23 10 t23 -10l104 -104l223 225q93 94 225.5 94t226.5 -94zM512 64l576 576l-192 192l-576 -576v-192h192z" />
-<glyph unicode="&#xf1fc;" horiz-adv-x="1792" d="M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5 t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z" />
-<glyph unicode="&#xf1fd;" horiz-adv-x="1792" d="M1792 128v-384h-1792v384q45 0 85 14t59 27.5t47 37.5q30 27 51.5 38t56.5 11t55.5 -11t52.5 -38q29 -25 47 -38t58 -27t86 -14q45 0 85 14.5t58 27t48 37.5q21 19 32.5 27t31 15t43.5 7q35 0 56.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14t85 14t59 27.5t47 37.5 q30 27 51.5 38t56.5 11q34 0 55.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14zM1792 448v-192q-35 0 -55.5 11t-52.5 38q-29 25 -47 38t-58 27t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-22 -19 -33 -27t-31 -15t-44 -7q-35 0 -56.5 11t-51.5 38q-29 25 -47 38t-58 27 t-86 14q-45 0 -85 -14.5t-58 -27t-48 -37.5q-21 -19 -32.5 -27t-31 -15t-43.5 -7q-35 0 -56.5 11t-51.5 38q-28 24 -47 37.5t-59 27.5t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-30 -27 -51.5 -38t-56.5 -11v192q0 80 56 136t136 56h64v448h256v-448h256v448h256v-448h256v448 h256v-448h64q80 0 136 -56t56 -136zM512 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1024 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51 t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1536 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150z" />
-<glyph unicode="&#xf1fe;" horiz-adv-x="2048" d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" />
-<glyph unicode="&#xf200;" horiz-adv-x="1792" d="M768 646l546 -546q-106 -108 -247.5 -168t-298.5 -60q-209 0 -385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103v-762zM955 640h773q0 -157 -60 -298.5t-168 -247.5zM1664 768h-768v768q209 0 385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf201;" horiz-adv-x="2048" d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435q0 -21 -19.5 -29.5t-35.5 7.5l-121 121l-633 -633q-10 -10 -23 -10t-23 10l-233 233l-416 -416l-192 192l585 585q10 10 23 10t23 -10l233 -233l464 464l-121 121q-16 16 -7.5 35.5t29.5 19.5h435q14 0 23 -9 t9 -23z" />
-<glyph unicode="&#xf202;" horiz-adv-x="1792" d="M1292 832q0 -6 10 -41q10 -29 25 -49.5t41 -34t44 -20t55 -16.5q325 -91 325 -332q0 -146 -105.5 -242.5t-254.5 -96.5q-59 0 -111.5 18.5t-91.5 45.5t-77 74.5t-63 87.5t-53.5 103.5t-43.5 103t-39.5 106.5t-35.5 95q-32 81 -61.5 133.5t-73.5 96.5t-104 64t-142 20 q-96 0 -183 -55.5t-138 -144.5t-51 -185q0 -160 106.5 -279.5t263.5 -119.5q177 0 258 95q56 63 83 116l84 -152q-15 -34 -44 -70l1 -1q-131 -152 -388 -152q-147 0 -269.5 79t-190.5 207.5t-68 274.5q0 105 43.5 206t116 176.5t172 121.5t204.5 46q87 0 159 -19t123.5 -50 t95 -80t72.5 -99t58.5 -117t50.5 -124.5t50 -130.5t55 -127q96 -200 233 -200q81 0 138.5 48.5t57.5 128.5q0 42 -19 72t-50.5 46t-72.5 31.5t-84.5 27t-87.5 34t-81 52t-65 82t-39 122.5q-3 16 -3 33q0 110 87.5 192t198.5 78q78 -3 120.5 -14.5t90.5 -53.5h-1 q12 -11 23 -24.5t26 -36t19 -27.5l-129 -99q-26 49 -54 70v1q-23 21 -97 21q-49 0 -84 -33t-35 -83z" />
-<glyph unicode="&#xf203;" d="M1432 484q0 173 -234 239q-35 10 -53 16.5t-38 25t-29 46.5q0 2 -2 8.5t-3 12t-1 7.5q0 36 24.5 59.5t60.5 23.5q54 0 71 -15h-1q20 -15 39 -51l93 71q-39 54 -49 64q-33 29 -67.5 39t-85.5 10q-80 0 -142 -57.5t-62 -137.5q0 -7 2 -23q16 -96 64.5 -140t148.5 -73 q29 -8 49 -15.5t45 -21.5t38.5 -34.5t13.5 -46.5v-5q1 -58 -40.5 -93t-100.5 -35q-97 0 -167 144q-23 47 -51.5 121.5t-48 125.5t-54 110.5t-74 95.5t-103.5 60.5t-147 24.5q-101 0 -192 -56t-144 -148t-50 -192v-1q4 -108 50.5 -199t133.5 -147.5t196 -56.5q186 0 279 110 q20 27 31 51l-60 109q-42 -80 -99 -116t-146 -36q-115 0 -191 87t-76 204q0 105 82 189t186 84q112 0 170 -53.5t104 -172.5q8 -21 25.5 -68.5t28.5 -76.5t31.5 -74.5t38.5 -74t45.5 -62.5t55.5 -53.5t66 -33t80 -13.5q107 0 183 69.5t76 174.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf204;" horiz-adv-x="2048" d="M1152 640q0 104 -40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM1920 640q0 104 -40.5 198.5 t-109.5 163.5t-163.5 109.5t-198.5 40.5h-386q119 -90 188.5 -224t69.5 -288t-69.5 -288t-188.5 -224h386q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM2048 640q0 -130 -51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5 t-136.5 204t-51 248.5t51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5z" />
-<glyph unicode="&#xf205;" horiz-adv-x="2048" d="M0 640q0 130 51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5t-51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5t-136.5 204t-51 248.5zM1408 128q104 0 198.5 40.5t163.5 109.5 t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" />
-<glyph unicode="&#xf206;" horiz-adv-x="2304" d="M762 384h-314q-40 0 -57.5 35t6.5 67l188 251q-65 31 -137 31q-132 0 -226 -94t-94 -226t94 -226t226 -94q115 0 203 72.5t111 183.5zM576 512h186q-18 85 -75 148zM1056 512l288 384h-480l-99 -132q105 -103 126 -252h165zM2176 448q0 132 -94 226t-226 94 q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94t226 94t94 226zM2304 448q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 97 39.5 183.5t109.5 149.5l-65 98l-353 -469 q-18 -26 -51 -26h-197q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q114 0 215 -55l137 183h-224q-26 0 -45 19t-19 45t19 45t45 19h384v-128h435l-85 128h-222q-26 0 -45 19t-19 45t19 45t45 19h256q33 0 53 -28l267 -400 q91 44 192 44q185 0 316.5 -131.5t131.5 -316.5z" />
-<glyph unicode="&#xf207;" d="M384 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1362 716l-72 384q-5 23 -22.5 37.5t-40.5 14.5 h-918q-23 0 -40.5 -14.5t-22.5 -37.5l-72 -384q-5 -30 14 -53t49 -23h1062q30 0 49 23t14 53zM1136 1328q0 20 -14 34t-34 14h-640q-20 0 -34 -14t-14 -34t14 -34t34 -14h640q20 0 34 14t14 34zM1536 603v-603h-128v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5v128h-768v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5v128h-128v603q0 112 25 223l103 454q9 78 97.5 137t230 89t312.5 30t312.5 -30t230 -89t97.5 -137l105 -454q23 -102 23 -223z" />
-<glyph unicode="&#xf208;" horiz-adv-x="2048" d="M1463 704q0 -35 -25 -60.5t-61 -25.5h-702q-36 0 -61 25.5t-25 60.5t25 60.5t61 25.5h702q36 0 61 -25.5t25 -60.5zM1677 704q0 86 -23 170h-982q-36 0 -61 25t-25 60q0 36 25 61t61 25h908q-88 143 -235 227t-320 84q-177 0 -327.5 -87.5t-238 -237.5t-87.5 -327 q0 -86 23 -170h982q36 0 61 -25t25 -60q0 -36 -25 -61t-61 -25h-908q88 -143 235.5 -227t320.5 -84q132 0 253 51.5t208 139t139 208t52 253.5zM2048 959q0 -35 -25 -60t-61 -25h-131q17 -85 17 -170q0 -167 -65.5 -319.5t-175.5 -263t-262.5 -176t-319.5 -65.5 q-246 0 -448.5 133t-301.5 350h-189q-36 0 -61 25t-25 61q0 35 25 60t61 25h132q-17 85 -17 170q0 167 65.5 319.5t175.5 263t262.5 176t320.5 65.5q245 0 447.5 -133t301.5 -350h188q36 0 61 -25t25 -61z" />
-<glyph unicode="&#xf209;" horiz-adv-x="1280" d="M953 1158l-114 -328l117 -21q165 451 165 518q0 56 -38 56q-57 0 -130 -225zM654 471l33 -88q37 42 71 67l-33 5.5t-38.5 7t-32.5 8.5zM362 1367q0 -98 159 -521q18 10 49 10q15 0 75 -5l-121 351q-75 220 -123 220q-19 0 -29 -17.5t-10 -37.5zM283 608q0 -36 51.5 -119 t117.5 -153t100 -70q14 0 25.5 13t11.5 27q0 24 -32 102q-13 32 -32 72t-47.5 89t-61.5 81t-62 32q-20 0 -45.5 -27t-25.5 -47zM125 273q0 -41 25 -104q59 -145 183.5 -227t281.5 -82q227 0 382 170q152 169 152 427q0 43 -1 67t-11.5 62t-30.5 56q-56 49 -211.5 75.5 t-270.5 26.5q-37 0 -49 -11q-12 -5 -12 -35q0 -34 21.5 -60t55.5 -40t77.5 -23.5t87.5 -11.5t85 -4t70 0h23q24 0 40 -19q15 -19 19 -55q-28 -28 -96 -54q-61 -22 -93 -46q-64 -46 -108.5 -114t-44.5 -137q0 -31 18.5 -88.5t18.5 -87.5l-3 -12q-4 -12 -4 -14 q-137 10 -146 216q-8 -2 -41 -2q2 -7 2 -21q0 -53 -40.5 -89.5t-94.5 -36.5q-82 0 -166.5 78t-84.5 159q0 34 33 67q52 -64 60 -76q77 -104 133 -104q12 0 26.5 8.5t14.5 20.5q0 34 -87.5 145t-116.5 111q-43 0 -70 -44.5t-27 -90.5zM11 264q0 101 42.5 163t136.5 88 q-28 74 -28 104q0 62 61 123t122 61q29 0 70 -15q-163 462 -163 567q0 80 41 130.5t119 50.5q131 0 325 -581q6 -17 8 -23q6 16 29 79.5t43.5 118.5t54 127.5t64.5 123t70.5 86.5t76.5 36q71 0 112 -49t41 -122q0 -108 -159 -550q61 -15 100.5 -46t58.5 -78t26 -93.5 t7 -110.5q0 -150 -47 -280t-132 -225t-211 -150t-278 -55q-111 0 -223 42q-149 57 -258 191.5t-109 286.5z" />
-<glyph unicode="&#xf20a;" horiz-adv-x="2048" d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206 q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307 t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14 t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" />
-<glyph unicode="&#xf20b;" d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5 t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf20c;" d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55 q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410 q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" />
-<glyph unicode="&#xf20d;" horiz-adv-x="1792" />
-<glyph unicode="&#xf20e;" horiz-adv-x="1792" />
-<glyph unicode="&#xf500;" horiz-adv-x="1792" />
-</font>
-</defs></svg> 
\ No newline at end of file
diff --git a/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf b/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf
deleted file mode 100644 (file)
index 96a3639..0000000
Binary files a/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf and /dev/null differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff b/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff
deleted file mode 100644 (file)
index 628b6a5..0000000
Binary files a/doc/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff and /dev/null differ
diff --git a/doc/_themes/sphinx_rtd_theme/static/js/badge_only.js b/doc/_themes/sphinx_rtd_theme/static/js/badge_only.js
new file mode 100644 (file)
index 0000000..526d723
--- /dev/null
@@ -0,0 +1 @@
+!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}});
\ No newline at end of file
index 432dc0c..839d07e 100644 (file)
@@ -1,156 +1 @@
-require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"sphinx-rtd-theme":[function(require,module,exports){
-var jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');
-
-// Sphinx theme nav state
-function ThemeNav () {
-
-    var nav = {
-        navBar: null,
-        win: null,
-        winScroll: false,
-        winResize: false,
-        linkScroll: false,
-        winPosition: 0,
-        winHeight: null,
-        docHeight: null,
-        isRunning: false
-    };
-
-    nav.enable = function () {
-        var self = this;
-
-        if (!self.isRunning) {
-            self.isRunning = true;
-            jQuery(function ($) {
-                self.init($);
-
-                self.reset();
-                self.win.on('hashchange', self.reset);
-
-                // Set scroll monitor
-                self.win.on('scroll', function () {
-                    if (!self.linkScroll) {
-                        self.winScroll = true;
-                    }
-                });
-                setInterval(function () { if (self.winScroll) self.onScroll(); }, 25);
-
-                // Set resize monitor
-                self.win.on('resize', function () {
-                    self.winResize = true;
-                });
-                setInterval(function () { if (self.winResize) self.onResize(); }, 25);
-                self.onResize();
-            });
-        };
-    };
-
-    nav.init = function ($) {
-        var doc = $(document),
-            self = this;
-
-        this.navBar = $('div.wy-side-scroll:first');
-        this.win = $(window);
-
-        // Set up javascript UX bits
-        $(document)
-            // Shift nav in mobile when clicking the menu.
-            .on('click', "[data-toggle='wy-nav-top']", function() {
-                $("[data-toggle='wy-nav-shift']").toggleClass("shift");
-                $("[data-toggle='rst-versions']").toggleClass("shift");
-            })
-
-            // Nav menu link click operations
-            .on('click', ".wy-menu-vertical .current ul li a", function() {
-                var target = $(this);
-                // Close menu when you click a link.
-                $("[data-toggle='wy-nav-shift']").removeClass("shift");
-                $("[data-toggle='rst-versions']").toggleClass("shift");
-                // Handle dynamic display of l3 and l4 nav lists
-                self.toggleCurrent(target);
-                self.hashChange();
-            })
-            .on('click', "[data-toggle='rst-current-version']", function() {
-                $("[data-toggle='rst-versions']").toggleClass("shift-up");
-            })
-
-        // Make tables responsive
-        $("table.docutils:not(.field-list)")
-            .wrap("<div class='wy-table-responsive'></div>");
-
-        // Add expand links to all parents of nested ul
-        $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
-            var link = $(this);
-                expand = $('<span class="toctree-expand"></span>');
-            expand.on('click', function (ev) {
-                self.toggleCurrent(link);
-                ev.stopPropagation();
-                return false;
-            });
-            link.prepend(expand);
-        });
-    };
-
-    nav.reset = function () {
-        // Get anchor from URL and open up nested nav
-        var anchor = encodeURI(window.location.hash);
-        if (anchor) {
-            try {
-                var link = $('.wy-menu-vertical')
-                    .find('[href="' + anchor + '"]');
-                $('.wy-menu-vertical li.toctree-l1 li.current')
-                    .removeClass('current');
-                link.closest('li.toctree-l2').addClass('current');
-                link.closest('li.toctree-l3').addClass('current');
-                link.closest('li.toctree-l4').addClass('current');
-            }
-            catch (err) {
-                console.log("Error expanding nav for anchor", err);
-            }
-        }
-    };
-
-    nav.onScroll = function () {
-        this.winScroll = false;
-        var newWinPosition = this.win.scrollTop(),
-            winBottom = newWinPosition + this.winHeight,
-            navPosition = this.navBar.scrollTop(),
-            newNavPosition = navPosition + (newWinPosition - this.winPosition);
-        if (newWinPosition < 0 || winBottom > this.docHeight) {
-            return;
-        }
-        this.navBar.scrollTop(newNavPosition);
-        this.winPosition = newWinPosition;
-    };
-
-    nav.onResize = function () {
-        this.winResize = false;
-        this.winHeight = this.win.height();
-        this.docHeight = $(document).height();
-    };
-
-    nav.hashChange = function () {
-        this.linkScroll = true;
-        this.win.one('hashchange', function () {
-            this.linkScroll = false;
-        });
-    };
-
-    nav.toggleCurrent = function (elem) {
-        var parent_li = elem.closest('li');
-        parent_li.siblings('li.current').removeClass('current');
-        parent_li.siblings().find('li.current').removeClass('current');
-        parent_li.find('> ul li.current').removeClass('current');
-        parent_li.toggleClass('current');
-    }
-
-    return nav;
-};
-
-module.exports.ThemeNav = ThemeNav();
-
-if (typeof(window) != 'undefined') {
-    window.SphinxRtdTheme = { StickyNav: module.exports.ThemeNav };
-}
-
-},{"jquery":"jquery"}]},{},["sphinx-rtd-theme"]);
+!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("<div class='wy-table-responsive'></div>"),n("table.docutils.footnote").wrap("<div class='wy-table-responsive footnote'></div>"),n("table.docutils.citation").wrap("<div class='wy-table-responsive citation'></div>"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n('<span class="toctree-expand"></span>'),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}t.length>0&&($(".wy-menu-vertical .current").removeClass("current"),t.addClass("current"),t.closest("li.toctree-l1").addClass("current"),t.closest("li.toctree-l1").parent().addClass("current"),t.closest("li.toctree-l1").addClass("current"),t.closest("li.toctree-l2").addClass("current"),t.closest("li.toctree-l3").addClass("current"),t.closest("li.toctree-l4").addClass("current"),t.closest("li.toctree-l5").addClass("current"),t[0].scrollIntoView())}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current"),e.siblings().find("li.current").removeClass("current"),e.find("> ul li.current").removeClass("current"),e.toggleClass("current")}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t<e.length&&!window.requestAnimationFrame;++t)window.requestAnimationFrame=window[e[t]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[e[t]+"CancelAnimationFrame"]||window[e[t]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(e,t){var i=(new Date).getTime(),o=Math.max(0,16-(i-n)),r=window.setTimeout((function(){e(i+o)}),o);return n=i+o,r}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(n){clearTimeout(n)})}()}).call(window)},function(n,e){n.exports=jQuery},function(n,e,t){}]);
\ No newline at end of file
index 3896d4d..fd0521f 100644 (file)
@@ -1,11 +1,18 @@
 [theme]
 inherit = basic
 stylesheet = css/theme.css
+pygments_style = default
 
 [options]
-typekit_id = hiw1hhg
-analytics_id = 
-sticky_navigation = False
+canonical_url =
+analytics_id =
+collapse_navigation = True
+sticky_navigation = True
+navigation_depth = 4
+includehidden = True
+titles_only =
 logo_only =
-collapse_navigation = False
 display_version = True
+prev_next_buttons_location = bottom
+style_external_links = False
+style_nav_header_background =
\ No newline at end of file
index 8b3eb79..7368659 100644 (file)
@@ -8,30 +8,27 @@
     </span>
     <div class="rst-other-versions">
       <dl>
-        <dt>Versions</dt>
+        <dt>{{ _('Versions') }}</dt>
         {% for slug, url in versions %}
           <dd><a href="{{ url }}">{{ slug }}</a></dd>
         {% endfor %}
       </dl>
       <dl>
-        <dt>Downloads</dt>
+        <dt>{{ _('Downloads') }}</dt>
         {% for type, url in downloads %}
           <dd><a href="{{ url }}">{{ type }}</a></dd>
         {% endfor %}
       </dl>
       <dl>
-        <dt>On Read the Docs</dt>
+        {# Translators: The phrase "Read the Docs" is not translated #}
+        <dt>{{ _('On Read the Docs') }}</dt>
           <dd>
-            <a href="//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}/?fromdocs={{ slug }}">Project Home</a>
+            <a href="//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}/?fromdocs={{ slug }}">{{ _('Project Home') }}</a>
           </dd>
           <dd>
-            <a href="//{{ PRODUCTION_DOMAIN }}/builds/{{ slug }}/?fromdocs={{ slug }}">Builds</a>
+            <a href="//{{ PRODUCTION_DOMAIN }}/builds/{{ slug }}/?fromdocs={{ slug }}">{{ _('Builds') }}</a>
           </dd>
       </dl>
-      <hr/>
-      Free document hosting provided by <a href="http://www.readthedocs.org">Read the Docs</a>.
-
     </div>
   </div>
 {% endif %}
-
index a737a49..bb0179b 100644 (file)
@@ -8,7 +8,7 @@ _h2load()
     _get_comp_words_by_ref cur prev
     case $cur in
         -*)
-            COMPREPLY=( $( compgen -W '--connection-window-bits --clients --verbose --ciphers --rate --no-tls-proto --connect-to --header-table-size --requests --log-file --base-uri --h1 --threads --npn-list --rate-period --data --version --connection-inactivity-timeout --timing-script-file --encoder-header-table-size --max-concurrent-streams --connection-active-timeout --input-file --help --window-bits --warm-up-time --duration --header ' -- "$cur" ) )
+            COMPREPLY=( $( compgen -W '--requests --clients --threads --input-file --max-concurrent-streams --window-bits --connection-window-bits --header --ciphers --tls13-ciphers --no-tls-proto --data --rate --rate-period --duration --warm-up-time --connection-active-timeout --connection-inactivity-timeout --timing-script-file --base-uri --npn-list --h1 --header-table-size --encoder-header-table-size --log-file --qlog-file-base --connect-to --rps --groups --no-udp-gso --max-udp-payload-size --verbose --version --help ' -- "$cur" ) )
             ;;
         *)
             _filedir
index 9a4cf19..d7d66b4 100644 (file)
@@ -8,7 +8,7 @@ _nghttp()
     _get_comp_words_by_ref cur prev
     case $cur in
         -*)
-            COMPREPLY=( $( compgen -W '--no-push --verbose --no-dep --get-assets --har --header-table-size --multiply --encoder-header-table-size --padding --hexdump --max-concurrent-streams --continuation --connection-window-bits --peer-max-concurrent-streams --timeout --data --no-content-length --version --color --cert --upgrade --remote-name --trailer --weight --help --key --null-out --window-bits --expect-continue --stat --no-verify-peer --header ' -- "$cur" ) )
+            COMPREPLY=( $( compgen -W '--verbose --null-out --remote-name --timeout --window-bits --connection-window-bits --get-assets --stat --header --trailer --cert --key --data --multiply --upgrade --weight --peer-max-concurrent-streams --header-table-size --encoder-header-table-size --padding --har --color --continuation --no-content-length --no-dep --hexdump --no-push --max-concurrent-streams --expect-continue --no-verify-peer --version --help ' -- "$cur" ) )
             ;;
         *)
             _filedir
index 92d1dfb..204e7db 100644 (file)
@@ -8,7 +8,7 @@ _nghttpd()
     _get_comp_words_by_ref cur prev
     case $cur in
         -*)
-            COMPREPLY=( $( compgen -W '--htdocs --verbose --daemon --echo-upload --error-gzip --push --header-table-size --encoder-header-table-size --padding --hexdump --max-concurrent-streams --no-tls --connection-window-bits --mime-types-file --no-content-length --workers --version --color --early-response --dh-param-file --trailer --address --window-bits --verify-client --help ' -- "$cur" ) )
+            COMPREPLY=( $( compgen -W '--address --daemon --verify-client --htdocs --verbose --no-tls --header-table-size --encoder-header-table-size --color --push --padding --max-concurrent-streams --workers --error-gzip --window-bits --connection-window-bits --dh-param-file --early-response --trailer --hexdump --echo-upload --mime-types-file --no-content-length --version --help ' -- "$cur" ) )
             ;;
         *)
             _filedir
index 0502cfd..89371ab 100644 (file)
@@ -8,7 +8,7 @@ _nghttpx()
     _get_comp_words_by_ref cur prev
     case $cur in
         -*)
-            COMPREPLY=( $( compgen -W '--worker-read-rate --include --frontend-http2-dump-response-header --tls-ticket-key-file --verify-client-cacert --max-response-header-fields --backend-http2-window-size --tls13-client-ciphers --frontend-keep-alive-timeout --backend-request-buffer --max-request-header-fields --backend-connect-timeout --tls-max-proto-version --conf --dns-lookup-timeout --backend-http2-max-concurrent-streams --worker-write-burst --npn-list --dns-max-try --fetch-ocsp-response-file --no-via --tls-session-cache-memcached-cert-file --no-http2-cipher-black-list --mruby-file --add-forwarded --client-no-http2-cipher-black-list --stream-read-timeout --client-ciphers --ocsp-update-interval --forwarded-for --accesslog-syslog --dns-cache-timeout --frontend-http2-read-timeout --listener-disable-timeout --ciphers --client-psk-secrets --strip-incoming-x-forwarded-for --no-server-rewrite --private-key-passwd-file --backend-keep-alive-timeout --backend-http-proxy-uri --frontend-max-requests --tls-no-postpone-early-data --rlimit-nofile --no-strip-incoming-x-forwarded-proto --tls-ticket-key-memcached-cert-file --no-verify-ocsp --forwarded-by --tls-session-cache-memcached-private-key-file --error-page --ocsp-startup --backend-write-timeout --tls-dyn-rec-warmup-threshold --tls-ticket-key-memcached-max-retry --frontend-http2-window-size --http2-no-cookie-crumbling --worker-read-burst --dh-param-file --accesslog-format --errorlog-syslog --redirect-https-port --request-header-field-buffer --api-max-request-body --frontend-http2-decoder-dynamic-table-size --errorlog-file --frontend-http2-max-concurrent-streams --psk-secrets --frontend-write-timeout --tls-ticket-key-cipher --read-burst --no-add-x-forwarded-proto --backend --server-name --insecure --backend-max-backoff --log-level --host-rewrite --tls-ticket-key-memcached-interval --frontend-http2-setting-timeout --frontend-http2-connection-window-size --worker-frontend-connections --syslog-facility --fastopen --no-location-rewrite --single-thread --tls-session-cache-memcached --no-ocsp --backend-response-buffer --tls-min-proto-version --workers --add-x-forwarded-for --no-server-push --worker-write-rate --add-request-header --backend-http2-settings-timeout --subcert --ignore-per-pattern-mruby-error --ecdh-curves --no-kqueue --help --frontend-frame-debug --tls-sct-dir --pid-file --frontend-http2-dump-request-header --daemon --write-rate --altsvc --backend-http2-decoder-dynamic-table-size --no-strip-incoming-early-data --user --verify-client-tolerate-expired --frontend-read-timeout --tls-ticket-key-memcached-max-fail --backlog --write-burst --backend-connections-per-host --tls-max-early-data --response-header-field-buffer --tls-ticket-key-memcached-address-family --padding --tls-session-cache-memcached-address-family --stream-write-timeout --cacert --tls-ticket-key-memcached-private-key-file --accesslog-write-early --backend-address-family --backend-http2-connection-window-size --tls13-ciphers --version --add-response-header --backend-read-timeout --frontend-http2-optimize-window-size --frontend --accesslog-file --http2-proxy --backend-http2-encoder-dynamic-table-size --client-private-key-file --single-process --client-cert-file --tls-ticket-key-memcached --tls-dyn-rec-idle-timeout --frontend-http2-optimize-write-buffer-size --verify-client --frontend-http2-encoder-dynamic-table-size --read-rate --backend-connections-per-frontend --strip-incoming-forwarded ' -- "$cur" ) )
+            COMPREPLY=( $( compgen -W '--backend --frontend --backlog --backend-address-family --backend-http-proxy-uri --workers --single-thread --read-rate --read-burst --write-rate --write-burst --worker-read-rate --worker-read-burst --worker-write-rate --worker-write-burst --worker-frontend-connections --backend-connections-per-host --backend-connections-per-frontend --rlimit-nofile --rlimit-memlock --backend-request-buffer --backend-response-buffer --fastopen --no-kqueue --frontend-http2-read-timeout --frontend-http3-read-timeout --frontend-read-timeout --frontend-write-timeout --frontend-keep-alive-timeout --stream-read-timeout --stream-write-timeout --backend-read-timeout --backend-write-timeout --backend-connect-timeout --backend-keep-alive-timeout --listener-disable-timeout --frontend-http2-setting-timeout --backend-http2-settings-timeout --backend-max-backoff --ciphers --tls13-ciphers --client-ciphers --tls13-client-ciphers --ecdh-curves --insecure --cacert --private-key-passwd-file --subcert --dh-param-file --npn-list --verify-client --verify-client-cacert --verify-client-tolerate-expired --client-private-key-file --client-cert-file --tls-min-proto-version --tls-max-proto-version --tls-ticket-key-file --tls-ticket-key-memcached --tls-ticket-key-memcached-address-family --tls-ticket-key-memcached-interval --tls-ticket-key-memcached-max-retry --tls-ticket-key-memcached-max-fail --tls-ticket-key-cipher --tls-ticket-key-memcached-cert-file --tls-ticket-key-memcached-private-key-file --fetch-ocsp-response-file --ocsp-update-interval --ocsp-startup --no-verify-ocsp --no-ocsp --tls-session-cache-memcached --tls-session-cache-memcached-address-family --tls-session-cache-memcached-cert-file --tls-session-cache-memcached-private-key-file --tls-dyn-rec-warmup-threshold --tls-dyn-rec-idle-timeout --no-http2-cipher-block-list --client-no-http2-cipher-block-list --tls-sct-dir --psk-secrets --client-psk-secrets --tls-no-postpone-early-data --tls-max-early-data --frontend-http2-max-concurrent-streams --backend-http2-max-concurrent-streams --frontend-http2-window-size --frontend-http2-connection-window-size --backend-http2-window-size --backend-http2-connection-window-size --http2-no-cookie-crumbling --padding --no-server-push --frontend-http2-optimize-write-buffer-size --frontend-http2-optimize-window-size --frontend-http2-encoder-dynamic-table-size --frontend-http2-decoder-dynamic-table-size --backend-http2-encoder-dynamic-table-size --backend-http2-decoder-dynamic-table-size --http2-proxy --log-level --accesslog-file --accesslog-syslog --accesslog-format --accesslog-write-early --errorlog-file --errorlog-syslog --syslog-facility --add-x-forwarded-for --strip-incoming-x-forwarded-for --no-add-x-forwarded-proto --no-strip-incoming-x-forwarded-proto --add-forwarded --strip-incoming-forwarded --forwarded-by --forwarded-for --no-via --no-strip-incoming-early-data --no-location-rewrite --host-rewrite --altsvc --http2-altsvc --add-request-header --add-response-header --request-header-field-buffer --max-request-header-fields --response-header-field-buffer --max-response-header-fields --error-page --server-name --no-server-rewrite --redirect-https-port --api-max-request-body --dns-cache-timeout --dns-lookup-timeout --dns-max-try --frontend-max-requests --frontend-http2-dump-request-header --frontend-http2-dump-response-header --frontend-frame-debug --daemon --pid-file --user --single-process --max-worker-processes --worker-process-grace-shutdown-period --mruby-file --ignore-per-pattern-mruby-error --frontend-quic-idle-timeout --frontend-quic-debug-log --quic-bpf-program-file --frontend-quic-early-data --frontend-quic-qlog-dir --frontend-quic-require-token --frontend-quic-congestion-controller --frontend-quic-secret-file --quic-server-id --frontend-quic-initial-rtt --no-quic-bpf --frontend-http3-window-size --frontend-http3-connection-window-size --frontend-http3-max-window-size --frontend-http3-max-connection-window-size --frontend-http3-max-concurrent-streams --conf --include --version --help ' -- "$cur" ) )
             ;;
         *)
             _filedir
index bc6401e..d6a82b6 100644 (file)
@@ -41,7 +41,7 @@ import sys, os
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 #sys.path.insert(0, os.path.abspath('.'))
 
-sys.path.append(os.path.abspath('@top_srcdir@/doc/_exts'))
+sys.path.insert(0, os.path.abspath('@top_srcdir@/doc/_exts'))
 
 # -- General configuration -----------------------------------------------------
 
@@ -50,7 +50,7 @@ sys.path.append(os.path.abspath('@top_srcdir@/doc/_exts'))
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinxcontrib.rubydomain']
+extensions = ['rubydomain.rubydomain']
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['@top_srcdir@/_templates']
index cfdb5d4..09eca2b 100644 (file)
@@ -7,86 +7,86 @@ Enums
     Error codes used in this library.  The code range is [-999, -500],
     inclusive. The following values are defined:
 
-    .. macro:: NGHTTP2_ERR_INVALID_ARGUMENT
+    .. enum:: NGHTTP2_ERR_INVALID_ARGUMENT
 
         (``-501``) 
         Invalid argument passed.
-    .. macro:: NGHTTP2_ERR_BUFFER_ERROR
+    .. enum:: NGHTTP2_ERR_BUFFER_ERROR
 
         (``-502``) 
         Out of buffer space.
-    .. macro:: NGHTTP2_ERR_UNSUPPORTED_VERSION
+    .. enum:: NGHTTP2_ERR_UNSUPPORTED_VERSION
 
         (``-503``) 
         The specified protocol version is not supported.
-    .. macro:: NGHTTP2_ERR_WOULDBLOCK
+    .. enum:: NGHTTP2_ERR_WOULDBLOCK
 
         (``-504``) 
         Used as a return value from :type:`nghttp2_send_callback`,
         :type:`nghttp2_recv_callback` and
         :type:`nghttp2_send_data_callback` to indicate that the operation
         would block.
-    .. macro:: NGHTTP2_ERR_PROTO
+    .. enum:: NGHTTP2_ERR_PROTO
 
         (``-505``) 
         General protocol error
-    .. macro:: NGHTTP2_ERR_INVALID_FRAME
+    .. enum:: NGHTTP2_ERR_INVALID_FRAME
 
         (``-506``) 
         The frame is invalid.
-    .. macro:: NGHTTP2_ERR_EOF
+    .. enum:: NGHTTP2_ERR_EOF
 
         (``-507``) 
         The peer performed a shutdown on the connection.
-    .. macro:: NGHTTP2_ERR_DEFERRED
+    .. enum:: NGHTTP2_ERR_DEFERRED
 
         (``-508``) 
         Used as a return value from
         :func:`nghttp2_data_source_read_callback` to indicate that data
         transfer is postponed.  See
         :func:`nghttp2_data_source_read_callback` for details.
-    .. macro:: NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE
+    .. enum:: NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE
 
         (``-509``) 
         Stream ID has reached the maximum value.  Therefore no stream ID
         is available.
-    .. macro:: NGHTTP2_ERR_STREAM_CLOSED
+    .. enum:: NGHTTP2_ERR_STREAM_CLOSED
 
         (``-510``) 
         The stream is already closed; or the stream ID is invalid.
-    .. macro:: NGHTTP2_ERR_STREAM_CLOSING
+    .. enum:: NGHTTP2_ERR_STREAM_CLOSING
 
         (``-511``) 
         RST_STREAM has been added to the outbound queue.  The stream is
         in closing state.
-    .. macro:: NGHTTP2_ERR_STREAM_SHUT_WR
+    .. enum:: NGHTTP2_ERR_STREAM_SHUT_WR
 
         (``-512``) 
         The transmission is not allowed for this stream (e.g., a frame
         with END_STREAM flag set has already sent).
-    .. macro:: NGHTTP2_ERR_INVALID_STREAM_ID
+    .. enum:: NGHTTP2_ERR_INVALID_STREAM_ID
 
         (``-513``) 
         The stream ID is invalid.
-    .. macro:: NGHTTP2_ERR_INVALID_STREAM_STATE
+    .. enum:: NGHTTP2_ERR_INVALID_STREAM_STATE
 
         (``-514``) 
         The state of the stream is not valid (e.g., DATA cannot be sent
         to the stream if response HEADERS has not been sent).
-    .. macro:: NGHTTP2_ERR_DEFERRED_DATA_EXIST
+    .. enum:: NGHTTP2_ERR_DEFERRED_DATA_EXIST
 
         (``-515``) 
         Another DATA frame has already been deferred.
-    .. macro:: NGHTTP2_ERR_START_STREAM_NOT_ALLOWED
+    .. enum:: NGHTTP2_ERR_START_STREAM_NOT_ALLOWED
 
         (``-516``) 
         Starting new stream is not allowed (e.g., GOAWAY has been sent
         and/or received).
-    .. macro:: NGHTTP2_ERR_GOAWAY_ALREADY_SENT
+    .. enum:: NGHTTP2_ERR_GOAWAY_ALREADY_SENT
 
         (``-517``) 
         GOAWAY has already been sent.
-    .. macro:: NGHTTP2_ERR_INVALID_HEADER_BLOCK
+    .. enum:: NGHTTP2_ERR_INVALID_HEADER_BLOCK
 
         (``-518``) 
         The received frame contains the invalid header block (e.g., There
@@ -94,110 +94,110 @@ Enums
         in US-ASCII character set and not lower cased; or the header name
         is zero-length string; or the header value contains multiple
         in-sequence NUL bytes).
-    .. macro:: NGHTTP2_ERR_INVALID_STATE
+    .. enum:: NGHTTP2_ERR_INVALID_STATE
 
         (``-519``) 
         Indicates that the context is not suitable to perform the
         requested operation.
-    .. macro:: NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE
+    .. enum:: NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE
 
         (``-521``) 
         The user callback function failed due to the temporal error.
-    .. macro:: NGHTTP2_ERR_FRAME_SIZE_ERROR
+    .. enum:: NGHTTP2_ERR_FRAME_SIZE_ERROR
 
         (``-522``) 
         The length of the frame is invalid, either too large or too small.
-    .. macro:: NGHTTP2_ERR_HEADER_COMP
+    .. enum:: NGHTTP2_ERR_HEADER_COMP
 
         (``-523``) 
         Header block inflate/deflate error.
-    .. macro:: NGHTTP2_ERR_FLOW_CONTROL
+    .. enum:: NGHTTP2_ERR_FLOW_CONTROL
 
         (``-524``) 
         Flow control error
-    .. macro:: NGHTTP2_ERR_INSUFF_BUFSIZE
+    .. enum:: NGHTTP2_ERR_INSUFF_BUFSIZE
 
         (``-525``) 
         Insufficient buffer size given to function.
-    .. macro:: NGHTTP2_ERR_PAUSE
+    .. enum:: NGHTTP2_ERR_PAUSE
 
         (``-526``) 
         Callback was paused by the application
-    .. macro:: NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS
+    .. enum:: NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS
 
         (``-527``) 
         There are too many in-flight SETTING frame and no more
         transmission of SETTINGS is allowed.
-    .. macro:: NGHTTP2_ERR_PUSH_DISABLED
+    .. enum:: NGHTTP2_ERR_PUSH_DISABLED
 
         (``-528``) 
         The server push is disabled.
-    .. macro:: NGHTTP2_ERR_DATA_EXIST
+    .. enum:: NGHTTP2_ERR_DATA_EXIST
 
         (``-529``) 
         DATA or HEADERS frame for a given stream has been already
         submitted and has not been fully processed yet.  Application
         should wait for the transmission of the previously submitted
         frame before submitting another.
-    .. macro:: NGHTTP2_ERR_SESSION_CLOSING
+    .. enum:: NGHTTP2_ERR_SESSION_CLOSING
 
         (``-530``) 
         The current session is closing due to a connection error or
         `nghttp2_session_terminate_session()` is called.
-    .. macro:: NGHTTP2_ERR_HTTP_HEADER
+    .. enum:: NGHTTP2_ERR_HTTP_HEADER
 
         (``-531``) 
         Invalid HTTP header field was received and stream is going to be
         closed.
-    .. macro:: NGHTTP2_ERR_HTTP_MESSAGING
+    .. enum:: NGHTTP2_ERR_HTTP_MESSAGING
 
         (``-532``) 
         Violation in HTTP messaging rule.
-    .. macro:: NGHTTP2_ERR_REFUSED_STREAM
+    .. enum:: NGHTTP2_ERR_REFUSED_STREAM
 
         (``-533``) 
         Stream was refused.
-    .. macro:: NGHTTP2_ERR_INTERNAL
+    .. enum:: NGHTTP2_ERR_INTERNAL
 
         (``-534``) 
         Unexpected internal error, but recovered.
-    .. macro:: NGHTTP2_ERR_CANCEL
+    .. enum:: NGHTTP2_ERR_CANCEL
 
         (``-535``) 
         Indicates that a processing was canceled.
-    .. macro:: NGHTTP2_ERR_SETTINGS_EXPECTED
+    .. enum:: NGHTTP2_ERR_SETTINGS_EXPECTED
 
         (``-536``) 
         When a local endpoint expects to receive SETTINGS frame, it
         receives an other type of frame.
-    .. macro:: NGHTTP2_ERR_TOO_MANY_SETTINGS
+    .. enum:: NGHTTP2_ERR_TOO_MANY_SETTINGS
 
         (``-537``) 
         When a local endpoint receives too many settings entries
         in a single SETTINGS frame.
-    .. macro:: NGHTTP2_ERR_FATAL
+    .. enum:: NGHTTP2_ERR_FATAL
 
         (``-900``) 
-        The errors < :macro:`NGHTTP2_ERR_FATAL` mean that the library is
-        under unexpected condition and processing was terminated (e.g.,
-        out of memory).  If application receives this error code, it must
-        stop using that :type:`nghttp2_session` object and only allowed
-        operation for that object is deallocate it using
-        `nghttp2_session_del()`.
-    .. macro:: NGHTTP2_ERR_NOMEM
+        The errors < :macro:`nghttp2_error.NGHTTP2_ERR_FATAL` mean that
+        the library is under unexpected condition and processing was
+        terminated (e.g., out of memory).  If application receives this
+        error code, it must stop using that :type:`nghttp2_session`
+        object and only allowed operation for that object is deallocate
+        it using `nghttp2_session_del()`.
+    .. enum:: NGHTTP2_ERR_NOMEM
 
         (``-901``) 
         Out of memory.  This is a fatal error.
-    .. macro:: NGHTTP2_ERR_CALLBACK_FAILURE
+    .. enum:: NGHTTP2_ERR_CALLBACK_FAILURE
 
         (``-902``) 
         The user callback function failed.  This is a fatal error.
-    .. macro:: NGHTTP2_ERR_BAD_CLIENT_MAGIC
+    .. enum:: NGHTTP2_ERR_BAD_CLIENT_MAGIC
 
         (``-903``) 
         Invalid client magic (see :macro:`NGHTTP2_CLIENT_MAGIC`) was
         received and further processing is not possible.
-    .. macro:: NGHTTP2_ERR_FLOODED
+    .. enum:: NGHTTP2_ERR_FLOODED
 
         (``-904``) 
         Possible flooding by peer was detected in this HTTP/2 session.
@@ -212,23 +212,23 @@ Enums
     
     The flags for header field name/value pair.
 
-    .. macro:: NGHTTP2_NV_FLAG_NONE
+    .. enum:: NGHTTP2_NV_FLAG_NONE
 
         (``0``) 
         No flag set.
-    .. macro:: NGHTTP2_NV_FLAG_NO_INDEX
+    .. enum:: NGHTTP2_NV_FLAG_NO_INDEX
 
         (``0x01``) 
         Indicates that this name/value pair must not be indexed ("Literal
         Header Field never Indexed" representation must be used in HPACK
         encoding).  Other implementation calls this bit as "sensitive".
-    .. macro:: NGHTTP2_NV_FLAG_NO_COPY_NAME
+    .. enum:: NGHTTP2_NV_FLAG_NO_COPY_NAME
 
         (``0x02``) 
         This flag is set solely by application.  If this flag is set, the
         library does not make a copy of header field name.  This could
         improve performance.
-    .. macro:: NGHTTP2_NV_FLAG_NO_COPY_VALUE
+    .. enum:: NGHTTP2_NV_FLAG_NO_COPY_VALUE
 
         (``0x04``) 
         This flag is set solely by application.  If this flag is set, the
@@ -240,54 +240,54 @@ Enums
     
     The frame types in HTTP/2 specification.
 
-    .. macro:: NGHTTP2_DATA
+    .. enum:: NGHTTP2_DATA
 
         (``0``) 
         The DATA frame.
-    .. macro:: NGHTTP2_HEADERS
+    .. enum:: NGHTTP2_HEADERS
 
         (``0x01``) 
         The HEADERS frame.
-    .. macro:: NGHTTP2_PRIORITY
+    .. enum:: NGHTTP2_PRIORITY
 
         (``0x02``) 
         The PRIORITY frame.
-    .. macro:: NGHTTP2_RST_STREAM
+    .. enum:: NGHTTP2_RST_STREAM
 
         (``0x03``) 
         The RST_STREAM frame.
-    .. macro:: NGHTTP2_SETTINGS
+    .. enum:: NGHTTP2_SETTINGS
 
         (``0x04``) 
         The SETTINGS frame.
-    .. macro:: NGHTTP2_PUSH_PROMISE
+    .. enum:: NGHTTP2_PUSH_PROMISE
 
         (``0x05``) 
         The PUSH_PROMISE frame.
-    .. macro:: NGHTTP2_PING
+    .. enum:: NGHTTP2_PING
 
         (``0x06``) 
         The PING frame.
-    .. macro:: NGHTTP2_GOAWAY
+    .. enum:: NGHTTP2_GOAWAY
 
         (``0x07``) 
         The GOAWAY frame.
-    .. macro:: NGHTTP2_WINDOW_UPDATE
+    .. enum:: NGHTTP2_WINDOW_UPDATE
 
         (``0x08``) 
         The WINDOW_UPDATE frame.
-    .. macro:: NGHTTP2_CONTINUATION
+    .. enum:: NGHTTP2_CONTINUATION
 
         (``0x09``) 
         The CONTINUATION frame.  This frame type won't be passed to any
         callbacks because the library processes this frame type and its
         preceding HEADERS/PUSH_PROMISE as a single frame.
-    .. macro:: NGHTTP2_ALTSVC
+    .. enum:: NGHTTP2_ALTSVC
 
         (``0x0a``) 
         The ALTSVC frame, which is defined in `RFC 7383
         <https://tools.ietf.org/html/rfc7838#section-4>`_.
-    .. macro:: NGHTTP2_ORIGIN
+    .. enum:: NGHTTP2_ORIGIN
 
         (``0x0c``) 
         The ORIGIN frame, which is defined by `RFC 8336
@@ -299,27 +299,27 @@ Enums
     The flags for HTTP/2 frames.  This enum defines all flags for all
     frames.
 
-    .. macro:: NGHTTP2_FLAG_NONE
+    .. enum:: NGHTTP2_FLAG_NONE
 
         (``0``) 
         No flag set.
-    .. macro:: NGHTTP2_FLAG_END_STREAM
+    .. enum:: NGHTTP2_FLAG_END_STREAM
 
         (``0x01``) 
         The END_STREAM flag.
-    .. macro:: NGHTTP2_FLAG_END_HEADERS
+    .. enum:: NGHTTP2_FLAG_END_HEADERS
 
         (``0x04``) 
         The END_HEADERS flag.
-    .. macro:: NGHTTP2_FLAG_ACK
+    .. enum:: NGHTTP2_FLAG_ACK
 
         (``0x01``) 
         The ACK flag.
-    .. macro:: NGHTTP2_FLAG_PADDED
+    .. enum:: NGHTTP2_FLAG_PADDED
 
         (``0x08``) 
         The PADDED flag.
-    .. macro:: NGHTTP2_FLAG_PRIORITY
+    .. enum:: NGHTTP2_FLAG_PRIORITY
 
         (``0x20``) 
         The PRIORITY flag.
@@ -328,31 +328,31 @@ Enums
 
     The SETTINGS ID.
 
-    .. macro:: NGHTTP2_SETTINGS_HEADER_TABLE_SIZE
+    .. enum:: NGHTTP2_SETTINGS_HEADER_TABLE_SIZE
 
         (``0x01``) 
         SETTINGS_HEADER_TABLE_SIZE
-    .. macro:: NGHTTP2_SETTINGS_ENABLE_PUSH
+    .. enum:: NGHTTP2_SETTINGS_ENABLE_PUSH
 
         (``0x02``) 
         SETTINGS_ENABLE_PUSH
-    .. macro:: NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS
+    .. enum:: NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS
 
         (``0x03``) 
         SETTINGS_MAX_CONCURRENT_STREAMS
-    .. macro:: NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE
+    .. enum:: NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE
 
         (``0x04``) 
         SETTINGS_INITIAL_WINDOW_SIZE
-    .. macro:: NGHTTP2_SETTINGS_MAX_FRAME_SIZE
+    .. enum:: NGHTTP2_SETTINGS_MAX_FRAME_SIZE
 
         (``0x05``) 
         SETTINGS_MAX_FRAME_SIZE
-    .. macro:: NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE
+    .. enum:: NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE
 
         (``0x06``) 
         SETTINGS_MAX_HEADER_LIST_SIZE
-    .. macro:: NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL
+    .. enum:: NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL
 
         (``0x08``) 
         SETTINGS_ENABLE_CONNECT_PROTOCOL
@@ -362,59 +362,59 @@ Enums
 
     The status codes for the RST_STREAM and GOAWAY frames.
 
-    .. macro:: NGHTTP2_NO_ERROR
+    .. enum:: NGHTTP2_NO_ERROR
 
         (``0x00``) 
         No errors.
-    .. macro:: NGHTTP2_PROTOCOL_ERROR
+    .. enum:: NGHTTP2_PROTOCOL_ERROR
 
         (``0x01``) 
         PROTOCOL_ERROR
-    .. macro:: NGHTTP2_INTERNAL_ERROR
+    .. enum:: NGHTTP2_INTERNAL_ERROR
 
         (``0x02``) 
         INTERNAL_ERROR
-    .. macro:: NGHTTP2_FLOW_CONTROL_ERROR
+    .. enum:: NGHTTP2_FLOW_CONTROL_ERROR
 
         (``0x03``) 
         FLOW_CONTROL_ERROR
-    .. macro:: NGHTTP2_SETTINGS_TIMEOUT
+    .. enum:: NGHTTP2_SETTINGS_TIMEOUT
 
         (``0x04``) 
         SETTINGS_TIMEOUT
-    .. macro:: NGHTTP2_STREAM_CLOSED
+    .. enum:: NGHTTP2_STREAM_CLOSED
 
         (``0x05``) 
         STREAM_CLOSED
-    .. macro:: NGHTTP2_FRAME_SIZE_ERROR
+    .. enum:: NGHTTP2_FRAME_SIZE_ERROR
 
         (``0x06``) 
         FRAME_SIZE_ERROR
-    .. macro:: NGHTTP2_REFUSED_STREAM
+    .. enum:: NGHTTP2_REFUSED_STREAM
 
         (``0x07``) 
         REFUSED_STREAM
-    .. macro:: NGHTTP2_CANCEL
+    .. enum:: NGHTTP2_CANCEL
 
         (``0x08``) 
         CANCEL
-    .. macro:: NGHTTP2_COMPRESSION_ERROR
+    .. enum:: NGHTTP2_COMPRESSION_ERROR
 
         (``0x09``) 
         COMPRESSION_ERROR
-    .. macro:: NGHTTP2_CONNECT_ERROR
+    .. enum:: NGHTTP2_CONNECT_ERROR
 
         (``0x0a``) 
         CONNECT_ERROR
-    .. macro:: NGHTTP2_ENHANCE_YOUR_CALM
+    .. enum:: NGHTTP2_ENHANCE_YOUR_CALM
 
         (``0x0b``) 
         ENHANCE_YOUR_CALM
-    .. macro:: NGHTTP2_INADEQUATE_SECURITY
+    .. enum:: NGHTTP2_INADEQUATE_SECURITY
 
         (``0x0c``) 
         INADEQUATE_SECURITY
-    .. macro:: NGHTTP2_HTTP_1_1_REQUIRED
+    .. enum:: NGHTTP2_HTTP_1_1_REQUIRED
 
         (``0x0d``) 
         HTTP_1_1_REQUIRED
@@ -425,22 +425,22 @@ Enums
     The flags used to set in *data_flags* output parameter in
     :type:`nghttp2_data_source_read_callback`.
 
-    .. macro:: NGHTTP2_DATA_FLAG_NONE
+    .. enum:: NGHTTP2_DATA_FLAG_NONE
 
         (``0``) 
         No flag set.
-    .. macro:: NGHTTP2_DATA_FLAG_EOF
+    .. enum:: NGHTTP2_DATA_FLAG_EOF
 
         (``0x01``) 
         Indicates EOF was sensed.
-    .. macro:: NGHTTP2_DATA_FLAG_NO_END_STREAM
+    .. enum:: NGHTTP2_DATA_FLAG_NO_END_STREAM
 
         (``0x02``) 
         Indicates that END_STREAM flag must not be set even if
         NGHTTP2_DATA_FLAG_EOF is set.  Usually this flag is used to send
         trailer fields with `nghttp2_submit_request()` or
         `nghttp2_submit_response()`.
-    .. macro:: NGHTTP2_DATA_FLAG_NO_COPY
+    .. enum:: NGHTTP2_DATA_FLAG_NO_COPY
 
         (``0x04``) 
         Indicates that application will send complete DATA frame in
@@ -455,22 +455,22 @@ Enums
     give the application the role of incoming HEADERS frame, we define
     several categories.
 
-    .. macro:: NGHTTP2_HCAT_REQUEST
+    .. enum:: NGHTTP2_HCAT_REQUEST
 
         (``0``) 
         The HEADERS frame is opening new stream, which is analogous to
         SYN_STREAM in SPDY.
-    .. macro:: NGHTTP2_HCAT_RESPONSE
+    .. enum:: NGHTTP2_HCAT_RESPONSE
 
         (``1``) 
         The HEADERS frame is the first response headers, which is
         analogous to SYN_REPLY in SPDY.
-    .. macro:: NGHTTP2_HCAT_PUSH_RESPONSE
+    .. enum:: NGHTTP2_HCAT_PUSH_RESPONSE
 
         (``2``) 
         The HEADERS frame is the first headers sent against reserved
         stream.
-    .. macro:: NGHTTP2_HCAT_HEADERS
+    .. enum:: NGHTTP2_HCAT_HEADERS
 
         (``3``) 
         The HEADERS frame which does not apply for the above categories,
@@ -483,15 +483,15 @@ Enums
     
     The flags for header inflation.
 
-    .. macro:: NGHTTP2_HD_INFLATE_NONE
+    .. enum:: NGHTTP2_HD_INFLATE_NONE
 
         (``0``) 
         No flag set.
-    .. macro:: NGHTTP2_HD_INFLATE_FINAL
+    .. enum:: NGHTTP2_HD_INFLATE_FINAL
 
         (``0x01``) 
         Indicates all headers were inflated.
-    .. macro:: NGHTTP2_HD_INFLATE_EMIT
+    .. enum:: NGHTTP2_HD_INFLATE_EMIT
 
         (``0x02``) 
         Indicates a header was emitted.
@@ -501,26 +501,26 @@ Enums
     
     State of stream as described in RFC 7540.
 
-    .. macro:: NGHTTP2_STREAM_STATE_IDLE
+    .. enum:: NGHTTP2_STREAM_STATE_IDLE
 
         (``1``) 
         idle state.
-    .. macro:: NGHTTP2_STREAM_STATE_OPEN,
+    .. enum:: NGHTTP2_STREAM_STATE_OPEN
 
         open state.
-    .. macro:: NGHTTP2_STREAM_STATE_RESERVED_LOCAL,
+    .. enum:: NGHTTP2_STREAM_STATE_RESERVED_LOCAL
 
         reserved (local) state.
-    .. macro:: NGHTTP2_STREAM_STATE_RESERVED_REMOTE,
+    .. enum:: NGHTTP2_STREAM_STATE_RESERVED_REMOTE
 
         reserved (remote) state.
-    .. macro:: NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL,
+    .. enum:: NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL
 
         half closed (local) state.
-    .. macro:: NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE,
+    .. enum:: NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE
 
         half closed (remote) state.
-    .. macro:: NGHTTP2_STREAM_STATE_CLOSED
+    .. enum:: NGHTTP2_STREAM_STATE_CLOSED
 
         closed state.
 
index 1070ebb..2b6c2e5 100644 (file)
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "H2LOAD" "1" "Jun 02, 2020" "1.41.0" "nghttp2"
+.TH "H2LOAD" "1" "Oct 19, 2021" "1.46.0" "nghttp2"
 .SH NAME
 h2load \- HTTP/2 benchmarking tool
 .
@@ -101,6 +101,7 @@ Default: \fB1\fP
 .TP
 .B \-w, \-\-window\-bits=<N>
 Sets the stream level initial window size to (2**<N>)\-1.
+For QUIC, <N> is capped to 26 (roughly 64MiB).
 .sp
 Default: \fB30\fP
 .UNINDENT
@@ -120,13 +121,21 @@ Add/Override a header to the requests.
 .INDENT 0.0
 .TP
 .B \-\-ciphers=<SUITE>
-Set allowed  cipher list.  The  format of the  string is
-described in OpenSSL ciphers(1).
+Set  allowed cipher  list  for TLSv1.2  or ealier.   The
+format of the string is described in OpenSSL ciphers(1).
 .sp
 Default: \fBECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:ECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-SHA384:ECDHE\-RSA\-AES256\-SHA384:ECDHE\-ECDSA\-AES128\-SHA256:ECDHE\-RSA\-AES128\-SHA256\fP
 .UNINDENT
 .INDENT 0.0
 .TP
+.B \-\-tls13\-ciphers=<SUITE>
+Set allowed cipher list for  TLSv1.3.  The format of the
+string is described in OpenSSL ciphers(1).
+.sp
+Default: \fBTLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256\fP
+.UNINDENT
+.INDENT 0.0
+.TP
 .B \-p, \-\-no\-tls\-proto=<PROTOID>
 Specify ALPN identifier of the  protocol to be used when
 accessing http URI without SSL/TLS.
@@ -168,7 +177,7 @@ option is 1s.
 .UNINDENT
 .INDENT 0.0
 .TP
-.B \-D, \-\-duration=<N>
+.B \-D, \-\-duration=<DURATION>
 Specifies the main duration for the measurements in case
 of timing\-based  benchmarking.  \fI\%\-D\fP  and \fI\%\-r\fP  are mutually
 exclusive.
@@ -220,7 +229,8 @@ to the  number of  script lines.   The scheme,  host and
 port defined in  the first URI are  used solely.  Values
 contained  in  other  URIs,  if  present,  are  ignored.
 Definition of a  base URI overrides all  scheme, host or
-port values.
+port   values.   \fI\%\-\-timing\-script\-file\fP   and  \fI\%\-\-rps\fP   are
+mutually exclusive.
 .UNINDENT
 .INDENT 0.0
 .TP
@@ -284,12 +294,45 @@ to buffering.  Status code is \-1 for failed streams.
 .UNINDENT
 .INDENT 0.0
 .TP
+.B \-\-qlog\-file\-base=<PATH>
+Enable qlog output and specify base file name for qlogs.
+Qlog  is emitted  for each connection.
+For  a  given  base  name "base", each  output file name
+becomes  "base.M.N.qlog"  where M is worker ID  and N is
+client ID (e.g. "base.0.3.qlog").
+Only effective in QUIC runs.
+.UNINDENT
+.INDENT 0.0
+.TP
 .B \-\-connect\-to=<HOST>[:<PORT>]
 Host and port to connect  instead of using the authority
 in <URI>.
 .UNINDENT
 .INDENT 0.0
 .TP
+.B \-\-rps=<N>
+Specify request  per second for each  client.  \fI\%\-\-rps\fP and
+\fI\%\-\-timing\-script\-file\fP are mutually exclusive.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-groups=<GROUPS>
+Specify the supported groups.
+.sp
+Default: \fBX25519:P\-256:P\-384:P\-521\fP
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-no\-udp\-gso
+Disable UDP GSO.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-max\-udp\-payload\-size=<SIZE>
+Specify the maximum outgoing UDP datagram payload size.
+.UNINDENT
+.INDENT 0.0
+.TP
 .B \-v, \-\-verbose
 Output debug information.
 .UNINDENT
index 265ae83..6617380 100644 (file)
@@ -76,6 +76,7 @@ OPTIONS
 .. option:: -w, --window-bits=<N>
 
     Sets the stream level initial window size to (2\*\*<N>)-1.
+    For QUIC, <N> is capped to 26 (roughly 64MiB).
 
     Default: ``30``
 
@@ -92,11 +93,18 @@ OPTIONS
 
 .. option:: --ciphers=<SUITE>
 
-    Set allowed  cipher list.  The  format of the  string is
-    described in OpenSSL ciphers(1).
+    Set  allowed cipher  list  for TLSv1.2  or ealier.   The
+    format of the string is described in OpenSSL ciphers(1).
 
     Default: ``ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256``
 
+.. option:: --tls13-ciphers=<SUITE>
+
+    Set allowed cipher list for  TLSv1.3.  The format of the
+    string is described in OpenSSL ciphers(1).
+
+    Default: ``TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256``
+
 .. option:: -p, --no-tls-proto=<PROTOID>
 
     Specify ALPN identifier of the  protocol to be used when
@@ -134,7 +142,7 @@ OPTIONS
     the rate option is not used.  The default value for this
     option is 1s.
 
-.. option:: -D, --duration=<N>
+.. option:: -D, --duration=<DURATION>
 
     Specifies the main duration for the measurements in case
     of timing-based  benchmarking.  :option:`-D`  and :option:`\-r`  are mutually
@@ -183,7 +191,8 @@ OPTIONS
     port defined in  the first URI are  used solely.  Values
     contained  in  other  URIs,  if  present,  are  ignored.
     Definition of a  base URI overrides all  scheme, host or
-    port values.
+    port   values.   :option:`--timing-script-file`   and  :option:`\--rps`   are
+    mutually exclusive.
 
 .. option:: -B, --base-uri=(<URI>|unix:<PATH>)
 
@@ -239,11 +248,39 @@ OPTIONS
     appear slightly  out of order with  multiple threads due
     to buffering.  Status code is -1 for failed streams.
 
+.. option:: --qlog-file-base=<PATH>
+
+    Enable qlog output and specify base file name for qlogs.
+    Qlog  is emitted  for each connection.
+    For  a  given  base  name "base", each  output file name
+    becomes  "base.M.N.qlog"  where M is worker ID  and N is
+    client ID (e.g. "base.0.3.qlog").
+    Only effective in QUIC runs.
+
 .. option:: --connect-to=<HOST>[:<PORT>]
 
     Host and port to connect  instead of using the authority
     in <URI>.
 
+.. option:: --rps=<N>
+
+    Specify request  per second for each  client.  :option:`--rps` and
+    :option:`--timing-script-file` are mutually exclusive.
+
+.. option:: --groups=<GROUPS>
+
+    Specify the supported groups.
+
+    Default: ``X25519:P-256:P-384:P-521``
+
+.. option:: --no-udp-gso
+
+    Disable UDP GSO.
+
+.. option:: --max-udp-payload-size=<SIZE>
+
+    Specify the maximum outgoing UDP datagram payload size.
+
 .. option:: -v, --verbose
 
     Output debug information.
index 583e745..c7e251c 100644 (file)
@@ -94,8 +94,8 @@ Macros
     
     Default maximum number of incoming concurrent streams.  Use
     `nghttp2_submit_settings()` with
-    :macro:`NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` to change the
-    maximum number of incoming concurrent streams.
+    :macro:`nghttp2_settings_id.NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS`
+    to change the maximum number of incoming concurrent streams.
     
     .. note::
     
index 6ed5fd7..3886a65 100755 (executable)
@@ -1,9 +1,11 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 # nghttp2 - HTTP/2 C Library
-
+#
+# Copyright (c) 2020 nghttp2 contributors
+# Copyright (c) 2020 ngtcp2 contributors
 # Copyright (c) 2012 Tatsuhiro Tsujikawa
-
+#
 # 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
 
 # Generates API reference from C source code.
 
-from __future__ import unicode_literals
-from __future__ import print_function # At least python 2.6 is required
 import re, sys, argparse, os.path
 
 class FunctionDoc:
-    def __init__(self, name, content, domain):
+    def __init__(self, name, content, domain, filename):
         self.name = name
         self.content = content
         self.domain = domain
         if self.domain == 'function':
             self.funcname = re.search(r'(nghttp2_[^ )]+)\(', self.name).group(1)
+        self.filename = filename
 
     def write(self, out):
         out.write('.. {}:: {}\n'.format(self.domain, self.name))
@@ -64,6 +65,26 @@ class StructDoc:
                     out.write('        {}\n'.format(line))
             out.write('\n')
 
+class EnumDoc:
+    def __init__(self, name, content, members):
+        self.name = name
+        self.content = content
+        self.members = members
+
+    def write(self, out):
+        if self.name:
+            out.write('.. type:: {}\n'.format(self.name))
+            out.write('\n')
+            for line in self.content:
+                out.write('    {}\n'.format(line))
+            out.write('\n')
+            for name, content in self.members:
+                out.write('    .. enum:: {}\n'.format(name))
+                out.write('\n')
+                for line in content:
+                    out.write('        {}\n'.format(line))
+            out.write('\n')
+
 class MacroDoc:
     def __init__(self, name, content):
         self.name = name
@@ -75,50 +96,76 @@ class MacroDoc:
         for line in self.content:
             out.write('    {}\n'.format(line))
 
-def make_api_ref(infiles):
+class MacroSectionDoc:
+    def __init__(self, content):
+        self.content = content
+
+    def write(self, out):
+        out.write('\n')
+        c = ' '.join(self.content).strip()
+        out.write(c)
+        out.write('\n')
+        out.write('-' * len(c))
+        out.write('\n\n')
+
+class TypedefDoc:
+    def __init__(self, name, content):
+        self.name = name
+        self.content = content
+
+    def write(self, out):
+        out.write('''.. type:: {}\n'''.format(self.name))
+        out.write('\n')
+        for line in self.content:
+            out.write('    {}\n'.format(line))
+
+def make_api_ref(infile):
     macros = []
     enums = []
     types = []
     functions = []
-    for infile in infiles:
-        while True:
+    while True:
+        line = infile.readline()
+        if not line:
+            break
+        elif line == '/**\n':
             line = infile.readline()
-            if not line:
-                break
-            elif line == '/**\n':
-                line = infile.readline()
-                doctype = line.split()[1]
-                if doctype == '@function':
-                    functions.append(process_function('function', infile))
-                elif doctype == '@functypedef':
-                    types.append(process_function('type', infile))
-                elif doctype == '@struct' or doctype == '@union':
-                    types.append(process_struct(infile))
-                elif doctype == '@enum':
-                    enums.append(process_enum(infile))
-                elif doctype == '@macro':
-                    macros.append(process_macro(infile))
+            doctype = line.split()[1]
+            if doctype == '@function':
+                functions.append(process_function('function', infile))
+            elif doctype == '@functypedef':
+                types.append(process_function('type', infile))
+            elif doctype == '@struct' or doctype == '@union':
+                types.append(process_struct(infile))
+            elif doctype == '@enum':
+                enums.append(process_enum(infile))
+            elif doctype == '@macro':
+                macros.append(process_macro(infile))
+            elif doctype == '@macrosection':
+                macros.append(process_macrosection(infile))
+            elif doctype == '@typedef':
+                types.append(process_typedef(infile))
     return macros, enums, types, functions
 
-    alldocs = [('Macros', macros),
-               ('Enums', enums),
-               ('Types (structs, unions and typedefs)', types),
-               ('Functions', functions)]
-
 def output(
-        indexfile, macrosfile, enumsfile, typesfile, funcsdir,
+        title, indexfile, macrosfile, enumsfile, typesfile, funcsdir,
         macros, enums, types, functions):
     indexfile.write('''
-API Reference
-=============
+{title}
+{titledecoration}
 
 .. toctree::
    :maxdepth: 1
 
-   macros
-   enums
-   types
-''')
+   {macros}
+   {enums}
+   {types}
+'''.format(
+    title=title, titledecoration='='*len(title),
+    macros=os.path.splitext(os.path.basename(macrosfile.name))[0],
+    enums=os.path.splitext(os.path.basename(enumsfile.name))[0],
+    types=os.path.splitext(os.path.basename(typesfile.name))[0],
+))
 
     for doc in functions:
         indexfile.write('   {}\n'.format(doc.funcname))
@@ -153,9 +200,10 @@ Types (structs, unions and typedefs)
 Synopsis
 --------
 
-*#include <nghttp2/nghttp2.h>*
+*#include <nghttp2/{filename}>*
 
-'''.format(funcname=doc.funcname, secul='='*len(doc.funcname)))
+'''.format(funcname=doc.funcname, secul='='*len(doc.funcname),
+           filename=doc.filename))
             doc.write(f)
 
 def process_macro(infile):
@@ -164,6 +212,17 @@ def process_macro(infile):
     macro_name = line.split()[1]
     return MacroDoc(macro_name, content)
 
+def process_macrosection(infile):
+    content = read_content(infile)
+    return MacroSectionDoc(content)
+
+def process_typedef(infile):
+    content = read_content(infile)
+    typedef = infile.readline()
+    typedef = re.sub(r';\n$', '', typedef)
+    typedef = re.sub(r'typedef ', '', typedef)
+    return TypedefDoc(typedef, content)
+
 def process_enum(infile):
     members = []
     enum_name = None
@@ -176,7 +235,7 @@ def process_enum(infile):
             member_content = read_content(infile)
             line = infile.readline()
             items = line.split()
-            member_name = items[0]
+            member_name = items[0].rstrip(',')
             if len(items) >= 3:
                 member_content.insert(0, '(``{}``) '\
                                       .format(' '.join(items[2:]).rstrip(',')))
@@ -185,7 +244,7 @@ def process_enum(infile):
             enum_name = line.rstrip().split()[1]
             enum_name = re.sub(r';$', '', enum_name)
             break
-    return StructDoc(enum_name, content, members, 'macro')
+    return EnumDoc(enum_name, content, members)
 
 def process_struct(infile):
     members = []
@@ -226,7 +285,9 @@ def process_function(domain, infile):
     func_proto = re.sub(r';\n$', '', func_proto)
     func_proto = re.sub(r'\s+', ' ', func_proto)
     func_proto = re.sub(r'NGHTTP2_EXTERN ', '', func_proto)
-    return FunctionDoc(func_proto, content, domain)
+    func_proto = re.sub(r'typedef ', '', func_proto)
+    filename = os.path.basename(infile.name)
+    return FunctionDoc(func_proto, content, domain, filename)
 
 def read_content(infile):
     content = []
@@ -251,6 +312,8 @@ def transform_content(content):
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description="Generate API reference")
+    parser.add_argument('--title', default='API Reference',
+                        help='title of index page')
     parser.add_argument('index', type=argparse.FileType('w'),
                         help='index output file')
     parser.add_argument('macros', type=argparse.FileType('w'),
@@ -269,12 +332,13 @@ if __name__ == '__main__':
     types = []
     funcs = []
     for infile in args.files:
-        m, e, t, f = make_api_ref(args.files)
+        m, e, t, f = make_api_ref(infile)
         macros.extend(m)
         enums.extend(e)
         types.extend(t)
         funcs.extend(f)
     funcs.sort(key=lambda x: x.funcname)
     output(
+        args.title,
         args.index, args.macros, args.enums, args.types, args.funcsdir,
         macros, enums, types, funcs)
index 8b8237d..4148abf 100644 (file)
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "NGHTTP" "1" "Jun 02, 2020" "1.41.0" "nghttp2"
+.TH "NGHTTP" "1" "Oct 19, 2021" "1.46.0" "nghttp2"
 .SH NAME
 nghttp \- HTTP/2 client
 .
index 46aea3b..e2817aa 100644 (file)
@@ -10,7 +10,7 @@ Synopsis
 .. function:: int nghttp2_check_authority(const uint8_t *value, size_t len)
 
     
-    Returns nonzero if the *value* which is supposed to the value of
+    Returns nonzero if the *value* which is supposed to be the value of the
     :authority or host header field is valid according to
     https://tools.ietf.org/html/rfc3986#section-3.2
     
diff --git a/doc/nghttp2_check_method.rst b/doc/nghttp2_check_method.rst
new file mode 100644 (file)
index 0000000..87570cd
--- /dev/null
@@ -0,0 +1,16 @@
+
+nghttp2_check_method
+====================
+
+Synopsis
+--------
+
+*#include <nghttp2/nghttp2.h>*
+
+.. function:: int nghttp2_check_method(const uint8_t *value, size_t len)
+
+    
+    Returns nonzero if the *value* which is supposed to be the value of
+    the :method header field is valid according to
+    https://datatracker.ietf.org/doc/html/rfc7231#section-4 and
+    https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
diff --git a/doc/nghttp2_check_path.rst b/doc/nghttp2_check_path.rst
new file mode 100644 (file)
index 0000000..24e3c24
--- /dev/null
@@ -0,0 +1,20 @@
+
+nghttp2_check_path
+==================
+
+Synopsis
+--------
+
+*#include <nghttp2/nghttp2.h>*
+
+.. function:: int nghttp2_check_path(const uint8_t *value, size_t len)
+
+    
+    Returns nonzero if the *value* which is supposed to be the value of
+    the :path header field is valid according to
+    https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.3
+    
+    *value* is valid if it merely consists of the allowed characters.
+    In particular, it does not check whether *value* follows the syntax
+    of path.  The allowed characters are all characters valid by
+    `nghttp2_check_header_value` minus SPC and HT.
index 11837c1..f0c965a 100644 (file)
@@ -27,5 +27,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index f7a533a..6da54ac 100644 (file)
@@ -14,22 +14,22 @@ Synopsis
     the *buf* of length *buflen*.
     
     If *buf* is not large enough to store the deflated header block,
-    this function fails with :macro:`NGHTTP2_ERR_INSUFF_BUFSIZE`.  The
-    caller should use `nghttp2_hd_deflate_bound()` to know the upper
-    bound of buffer size required to deflate given header name/value
-    pairs.
+    this function fails with
+    :macro:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`.  The caller
+    should use `nghttp2_hd_deflate_bound()` to know the upper bound of
+    buffer size required to deflate given header name/value pairs.
     
     Once this function fails, subsequent call of this function always
-    returns :macro:`NGHTTP2_ERR_HEADER_COMP`.
+    returns :macro:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`.
     
     After this function returns, it is safe to delete the *nva*.
     
     This function returns the number of bytes written to *buf* if it
     succeeds, or one of the following negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_HEADER_COMP`
+    :macro:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
         Deflation process has failed.
-    :macro:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
         The provided *buflen* size is too small to hold the output.
index 4ad3bae..f19c0d1 100644 (file)
@@ -15,21 +15,22 @@ Synopsis
     must be set in len field of :type:`nghttp2_vec`.  If and only if
     one chunk is filled up completely, next chunk will be used.  If
     *vec* is not large enough to store the deflated header block, this
-    function fails with :macro:`NGHTTP2_ERR_INSUFF_BUFSIZE`.  The caller
+    function fails with
+    :macro:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`.  The caller
     should use `nghttp2_hd_deflate_bound()` to know the upper bound of
     buffer size required to deflate given header name/value pairs.
     
     Once this function fails, subsequent call of this function always
-    returns :macro:`NGHTTP2_ERR_HEADER_COMP`.
+    returns :macro:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`.
     
     After this function returns, it is safe to delete the *nva*.
     
     This function returns the number of bytes written to *vec* if it
     succeeds, or one of the following negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_HEADER_COMP`
+    :macro:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
         Deflation process has failed.
-    :macro:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
         The provided *buflen* size is too small to hold the output.
index 717d231..05af983 100644 (file)
@@ -20,5 +20,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index 6b40a10..17757c3 100644 (file)
@@ -26,9 +26,9 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_STATE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
         The function is called while header block is being inflated.
         Probably, application missed to call
         `nghttp2_hd_inflate_end_headers()`.
index e537764..0e2fd0c 100644 (file)
@@ -16,7 +16,8 @@ Synopsis
     
     Inflates name/value block stored in *in* with length *inlen*.  This
     function performs decompression.  For each successful emission of
-    header name/value pair, :macro:`NGHTTP2_HD_INFLATE_EMIT` is set in
+    header name/value pair,
+    :macro:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in
     *\*inflate_flags* and name/value pair is assigned to the *nv_out*
     and the function returns.  The caller must not free the members of
     *nv_out*.
@@ -39,11 +40,11 @@ Synopsis
     This function returns the number of bytes processed if it succeeds,
     or one of the following negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_HEADER_COMP`
+    :macro:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
         Inflation process has failed.
-    :macro:`NGHTTP2_ERR_BUFFER_ERROR`
+    :macro:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR`
         The header field name or value is too large.
     
     Example follows::
index 644f56c..25abaa8 100644 (file)
@@ -12,7 +12,8 @@ Synopsis
     
     Inflates name/value block stored in *in* with length *inlen*.  This
     function performs decompression.  For each successful emission of
-    header name/value pair, :macro:`NGHTTP2_HD_INFLATE_EMIT` is set in
+    header name/value pair,
+    :macro:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in
     *\*inflate_flags* and name/value pair is assigned to the *nv_out*
     and the function returns.  The caller must not free the members of
     *nv_out*.
@@ -28,8 +29,9 @@ Synopsis
     for the next header block input.
     
     In other words, if *in_final* is nonzero, and this function returns
-    *inlen*, you can assert that :macro:`NGHTTP2_HD_INFLATE_FINAL` is
-    set in *\*inflate_flags*.
+    *inlen*, you can assert that
+    :macro:`nghttp2_hd_inflate_final.NGHTTP2_HD_INFLATE_FINAL` is set in
+    *\*inflate_flags*.
     
     The caller can feed complete compressed header block.  It also can
     feed it in several chunks.  The caller must set *in_final* to
@@ -39,11 +41,11 @@ Synopsis
     This function returns the number of bytes processed if it succeeds,
     or one of the following negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_HEADER_COMP`
+    :macro:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
         Inflation process has failed.
-    :macro:`NGHTTP2_ERR_BUFFER_ERROR`
+    :macro:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR`
         The header field name or value is too large.
     
     Example follows::
index cfd2212..bf0d650 100644 (file)
@@ -17,5 +17,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index 4dcfb64..f406398 100644 (file)
@@ -18,5 +18,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index 82a704c..2dff74c 100644 (file)
@@ -16,4 +16,4 @@ Synopsis
     `nghttp2_hd_deflate_bound()`.  The default value is 64KiB.  If
     application attempts to send header fields larger than this limit,
     the transmission of the frame fails with error code
-    :macro:`NGHTTP2_ERR_FRAME_SIZE_ERROR`.
+    :macro:`nghttp2_error.NGHTTP2_ERR_FRAME_SIZE_ERROR`.
index 42226e7..06349e7 100644 (file)
@@ -15,5 +15,5 @@ Synopsis
     received.  If this option is set to nonzero, the library won't send
     PING frame with ACK flag set in the response for incoming PING
     frame.  The application can send PING frame with ACK flag set using
-    `nghttp2_submit_ping()` with :macro:`NGHTTP2_FLAG_ACK` as flags
-    parameter.
+    `nghttp2_submit_ping()` with :macro:`nghttp2_flag.NGHTTP2_FLAG_ACK`
+    as flags parameter.
index e45fe54..0c02590 100644 (file)
@@ -23,4 +23,5 @@ Synopsis
     If this option is not used or used with zero value, if MAGIC does
     not match :macro:`NGHTTP2_CLIENT_MAGIC`, `nghttp2_session_recv()`
     and `nghttp2_session_mem_recv()` will return error
-    :macro:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal error.
+    :macro:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal
+    error.
index 17dc157..2d88ddf 100644 (file)
@@ -22,8 +22,8 @@ Synopsis
     This function returns the number of bytes written in *buf*, or one
     of the following negative error codes:
     
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *iv* contains duplicate settings ID or invalid value.
     
-    :macro:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
         The provided *buflen* size is too small to hold the output.
index 809db59..c6e8d9a 100644 (file)
@@ -21,5 +21,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index 5678cfc..3999a1c 100644 (file)
@@ -11,5 +11,5 @@ Synopsis
 
     
     Sets callback function invoked when
-    :macro:`NGHTTP2_DATA_FLAG_NO_COPY` is used in
+    :macro:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in
     :type:`nghttp2_data_source_read_callback` to avoid data copy.
index d11def1..6c457d0 100644 (file)
@@ -30,8 +30,8 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         Attempted to depend on itself; or no stream exist for the given
         *stream_id*; or *stream_id* is 0
index 6f0c261..60c1c2e 100644 (file)
@@ -25,5 +25,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index 863d429..b1467a0 100644 (file)
@@ -25,5 +25,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index 22bef5a..ca91493 100644 (file)
@@ -25,5 +25,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index c4d08f2..34dd712 100644 (file)
@@ -23,9 +23,9 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *stream_id* is 0.
-    :macro:`NGHTTP2_ERR_INVALID_STATE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
         Automatic WINDOW_UPDATE is not disabled.
index c263cd6..926b706 100644 (file)
@@ -18,7 +18,7 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_STATE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
         Automatic WINDOW_UPDATE is not disabled.
index 694ee50..3c21b6e 100644 (file)
@@ -18,9 +18,9 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *stream_id* is 0.
-    :macro:`NGHTTP2_ERR_INVALID_STATE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
         Automatic WINDOW_UPDATE is not disabled.
index e9a70b1..15ccf2b 100644 (file)
@@ -39,9 +39,9 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         Attempted to depend on itself; or stream denoted by *stream_id*
         already exists; or *stream_id* cannot be used to create idle
         stream (in other words, local endpoint has already opened
index 4e4d7f7..806acbf 100644 (file)
@@ -11,7 +11,7 @@ Synopsis
 
     
     Processes data *in* as an input from the remote endpoint.  The
-    *inlen* indicates the number of bytes in the *in*.
+    *inlen* indicates the number of bytes to receive in the *in*.
     
     This function behaves like `nghttp2_session_recv()` except that it
     does not use :type:`nghttp2_recv_callback` to receive data; the
@@ -20,26 +20,26 @@ Synopsis
     are called in the same way as they are in `nghttp2_session_recv()`.
     
     In the current implementation, this function always tries to
-    processes all input data unless either an error occurs or
-    :macro:`NGHTTP2_ERR_PAUSE` is returned from
+    processes *inlen* bytes of input data unless either an error occurs or
+    :macro:`nghttp2_error.NGHTTP2_ERR_PAUSE` is returned from
     :type:`nghttp2_on_header_callback` or
     :type:`nghttp2_on_data_chunk_recv_callback`.  If
-    :macro:`NGHTTP2_ERR_PAUSE` is used, the return value includes the
-    number of bytes which was used to produce the data or frame for the
-    callback.
+    :macro:`nghttp2_error.NGHTTP2_ERR_PAUSE` is used, the return value
+    includes the number of bytes which was used to produce the data or
+    frame for the callback.
     
     This function returns the number of processed bytes, or one of the
     following negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
         The callback function failed.
-    :macro:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`
+    :macro:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`
         Invalid client magic was detected.  This error only returns
         when *session* was configured as server and
         `nghttp2_option_set_no_recv_client_magic()` is not used with
         nonzero value.
-    :macro:`NGHTTP2_ERR_FLOODED`
+    :macro:`nghttp2_error.NGHTTP2_ERR_FLOODED`
         Flooding was detected in this HTTP/2 session, and it must be
         closed.  This is most likely caused by misbehaviour of peer.
index a14e700..2177d74 100644 (file)
@@ -34,7 +34,7 @@ Synopsis
     *\*data_ptr* if it succeeds, or one of the following negative error
     codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
     
     .. note::
index ea696d9..753a45b 100644 (file)
@@ -14,8 +14,8 @@ Synopsis
     
     This function receives as many frames as possible until the user
     callback :type:`nghttp2_recv_callback` returns
-    :macro:`NGHTTP2_ERR_WOULDBLOCK`.  This function calls several
-    callback functions which are passed when initializing the
+    :macro:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`.  This function calls
+    several callback functions which are passed when initializing the
     *session*.  Here is the simple time chart which tells when each
     callback is invoked:
     
@@ -60,17 +60,17 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_EOF`
+    :macro:`nghttp2_error.NGHTTP2_ERR_EOF`
         The remote peer did shutdown on the connection.
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
         The callback function failed.
-    :macro:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`
+    :macro:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`
         Invalid client magic was detected.  This error only returns
         when *session* was configured as server and
         `nghttp2_option_set_no_recv_client_magic()` is not used with
         nonzero value.
-    :macro:`NGHTTP2_ERR_FLOODED`
+    :macro:`nghttp2_error.NGHTTP2_ERR_FLOODED`
         Flooding was detected in this HTTP/2 session, and it must be
         closed.  This is most likely caused by misbehaviour of peer.
index daa9b8f..bef668a 100644 (file)
@@ -16,7 +16,7 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The stream does not exist; or no deferred data exist.
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index c01b5ec..e6ced59 100644 (file)
@@ -14,12 +14,14 @@ Synopsis
     
     This function retrieves the highest prioritized frame from the
     outbound queue and sends it to the remote peer.  It does this as
-    many as possible until the user callback
+    many times as possible until the user callback
     :type:`nghttp2_send_callback` returns
-    :macro:`NGHTTP2_ERR_WOULDBLOCK` or the outbound queue becomes empty.
-    This function calls several callback functions which are passed
-    when initializing the *session*.  Here is the simple time chart
-    which tells when each callback is invoked:
+    :macro:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`, the outbound queue
+    becomes empty or flow control is triggered (remote window size
+    becomes depleted or maximum number of concurrent streams is
+    reached).  This function calls several callback functions which are
+    passed when initializing the *session*.  Here is the simple time
+    chart which tells when each callback is invoked:
     
     1. Get the next frame to send from outbound queue.
     
@@ -37,7 +39,7 @@ Synopsis
     
     6. :type:`nghttp2_before_frame_send_callback` is invoked.
     
-    7. If :macro:`NGHTTP2_ERR_CANCEL` is returned from
+    7. If :macro:`nghttp2_error.NGHTTP2_ERR_CANCEL` is returned from
        :type:`nghttp2_before_frame_send_callback`, the current frame
        transmission is canceled, and
        :type:`nghttp2_on_frame_not_send_callback` is invoked.  Abort
@@ -55,7 +57,7 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
         The callback function failed.
index 7350180..daa27ae 100644 (file)
@@ -25,5 +25,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index 482e651..0a6f371 100644 (file)
@@ -25,5 +25,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index 35d1e39..4e9162f 100644 (file)
@@ -25,5 +25,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index c818ffb..22282ea 100644 (file)
@@ -17,7 +17,7 @@ Synopsis
     to transmission queue.
     
     The *flags* is currently ignored and should be
-    :macro:`NGHTTP2_FLAG_NONE`.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
     
     This sounds similar to `nghttp2_submit_window_update()`, but there
     are 2 differences.  The first difference is that this function
@@ -36,7 +36,7 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *stream_id* is negative.
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index 5f2efa9..aaf9455 100644 (file)
@@ -17,7 +17,7 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *next_stream_id* is strictly less than the value
         `nghttp2_session_get_next_stream_id()` returns; or
         *next_stream_id* is invalid (e.g., even integer for client, or
index 6700650..f384751 100644 (file)
@@ -22,5 +22,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The stream does not exist
index 2b85319..803349f 100644 (file)
@@ -30,5 +30,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index fd31508..47b77cf 100644 (file)
@@ -28,7 +28,7 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *last_stream_id* is invalid.
index 58be39d..5d75c20 100644 (file)
@@ -47,9 +47,9 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *settings_payload* is badly formed.
-    :macro:`NGHTTP2_ERR_PROTO`
+    :macro:`nghttp2_error.NGHTTP2_ERR_PROTO`
         The stream ID 1 is already used or closed; or is not available.
index 3976850..453b5b9 100644 (file)
@@ -39,9 +39,9 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *settings_payload* is badly formed.
-    :macro:`NGHTTP2_ERR_PROTO`
+    :macro:`nghttp2_error.NGHTTP2_ERR_PROTO`
         The stream ID 1 is already used or closed; or is not available.
index d967c7b..4ad7d7c 100644 (file)
@@ -12,4 +12,4 @@ Synopsis
     
     Returns state of *stream*.  The root stream retrieved by
     `nghttp2_session_get_root_stream()` will have stream state
-    :macro:`NGHTTP2_STREAM_STATE_IDLE`.
+    :macro:`nghttp2_stream_proto_state.NGHTTP2_STREAM_STATE_IDLE`.
index c6735a0..3612769 100644 (file)
@@ -16,7 +16,7 @@ Synopsis
     `RFC 7383 <https://tools.ietf.org/html/rfc7838#section-4>`_.
     
     The *flags* is currently ignored and should be
-    :macro:`NGHTTP2_FLAG_NONE`.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
     
     The *origin* points to the origin this alternative service is
     associated with.  The *origin_len* is the length of the origin.  If
@@ -26,16 +26,16 @@ Synopsis
     
     The ALTSVC frame is only usable from server side.  If this function
     is invoked with client side session, this function returns
-    :macro:`NGHTTP2_ERR_INVALID_STATE`.
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`.
     
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory
-    :macro:`NGHTTP2_ERR_INVALID_STATE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
         The function is called from client side session
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The sum of *origin_len* and *field_value_len* is larger than
         16382; or *origin_len* is 0 while *stream_id* is 0; or
         *origin_len* is not 0 while *stream_id* is not 0.
index ef7054a..cb68f2b 100644 (file)
@@ -12,8 +12,8 @@ Synopsis
     
     Submits one or more DATA frames to the stream *stream_id*.  The
     data to be sent are provided by *data_prd*.  If *flags* contains
-    :macro:`NGHTTP2_FLAG_END_STREAM`, the last DATA frame has END_STREAM
-    flag set.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, the last DATA frame
+    has END_STREAM flag set.
     
     This function does not take ownership of the *data_prd*.  The
     function copies the members of the *data_prd*.
@@ -21,27 +21,28 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_DATA_EXIST`
+    :macro:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
         DATA or HEADERS has been already submitted and not fully
         processed yet.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *stream_id* is 0.
-    :macro:`NGHTTP2_ERR_STREAM_CLOSED`
+    :macro:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED`
         The stream was already closed; or the *stream_id* is invalid.
     
     .. note::
     
       Currently, only one DATA or HEADERS is allowed for a stream at a
       time.  Submitting these frames more than once before first DATA
-      or HEADERS is finished results in :macro:`NGHTTP2_ERR_DATA_EXIST`
-      error code.  The earliest callback which tells that previous
-      frame is done is :type:`nghttp2_on_frame_send_callback`.  In side
-      that callback, new data can be submitted using
-      `nghttp2_submit_data()`.  Of course, all data except for last one
-      must not have :macro:`NGHTTP2_FLAG_END_STREAM` flag set in
-      *flags*.  This sounds a bit complicated, and we recommend to use
+      or HEADERS is finished results in
+      :macro:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` error code.  The
+      earliest callback which tells that previous frame is done is
+      :type:`nghttp2_on_frame_send_callback`.  In side that callback,
+      new data can be submitted using `nghttp2_submit_data()`.  Of
+      course, all data except for last one must not have
+      :macro:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` flag set in *flags*.
+      This sounds a bit complicated, and we recommend to use
       `nghttp2_submit_request()` and `nghttp2_submit_response()` to
       avoid this cascading issue.  The experience shows that for HTTP
       use, these two functions are enough to implement both client and
index b30e53e..03b9d1b 100644 (file)
@@ -31,16 +31,17 @@ Synopsis
     
     The standard HTTP/2 frame cannot be sent with this function, so
     *type* must be strictly grater than 0x9.  Otherwise, this function
-    will fail with error code :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`.
+    will fail with error code
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`.
     
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_INVALID_STATE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
         If :type:`nghttp2_pack_extension_callback` is not set.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         If  *type* specifies  standard  HTTP/2 frame  type.  The  frame
         types  in the  rage [0x0,  0x9], both  inclusive, are  standard
         HTTP/2 frame type, and cannot be sent using this function.
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory
index 93a99f1..5219b7b 100644 (file)
@@ -16,7 +16,7 @@ Synopsis
     The pre-defined error code is one of :macro:`nghttp2_error_code`.
     
     The *flags* is currently ignored and should be
-    :macro:`NGHTTP2_FLAG_NONE`.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
     
     The *last_stream_id* is peer's stream ID or 0.  So if *session* is
     initialized as client, *last_stream_id* must be even or 0.  If
@@ -46,8 +46,8 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *opaque_data_len* is too large; the *last_stream_id* is
         invalid.
index 5b2448e..d7deb64 100644 (file)
@@ -13,10 +13,10 @@ Synopsis
     Submits HEADERS frame. The *flags* is bitwise OR of the
     following values:
     
-    * :macro:`NGHTTP2_FLAG_END_STREAM`
+    * :macro:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`
     
-    If *flags* includes :macro:`NGHTTP2_FLAG_END_STREAM`, this frame has
-    END_STREAM flag set.
+    If *flags* includes :macro:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`,
+    this frame has END_STREAM flag set.
     
     The library handles the CONTINUATION frame internally and it
     correctly sets END_HEADERS to the last sequence of the PUSH_PROMISE
@@ -34,8 +34,8 @@ Synopsis
     this function will copy its data members.
     
     The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
-    :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight`` is
-    strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
+    :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight``
+    is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
     :macro:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
     :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`.
     
@@ -48,12 +48,12 @@ Synopsis
     This function creates copies of all name/value pairs in *nva*.  It
     also lower-cases all names in *nva*.  The order of elements in
     *nva* is preserved.  For header fields with
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
-    and value are not copied respectively.  With
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
-    pass header field name in lowercase.  The application should
-    maintain the references to them until
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+    header field name and value are not copied respectively.  With
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+    is responsible to pass header field name in lowercase.  The
+    application should maintain the references to them until
     :type:`nghttp2_on_frame_send_callback` or
     :type:`nghttp2_on_frame_not_send_callback` is called.
     
@@ -71,19 +71,19 @@ Synopsis
     *stream_id* is -1.  Otherwise, this function returns 0 if it
     succeeds, or one of the following negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
         No stream ID is available because maximum stream ID was
         reached.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *stream_id* is 0; or trying to depend on itself (stream ID
         equals ``pri_spec->stream_id``).
-    :macro:`NGHTTP2_ERR_DATA_EXIST`
+    :macro:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
         DATA or HEADERS has been already submitted and not fully
         processed yet.  This happens if stream denoted by *stream_id*
         is in reserved state.
-    :macro:`NGHTTP2_ERR_PROTO`
+    :macro:`nghttp2_error.NGHTTP2_ERR_PROTO`
         The *stream_id* is -1, and *session* is server session.
     
     .. warning::
index 790441d..eda04f8 100644 (file)
@@ -16,7 +16,7 @@ Synopsis
     `RFC 8336 <https://tools.ietf.org/html/rfc8336>`_.
     
     The *flags* is currently ignored and should be
-    :macro:`NGHTTP2_FLAG_NONE`.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
     
     The *ov* points to the array of origins.  The *nov* specifies the
     number of origins included in *ov*.  This function creates copies
@@ -24,12 +24,12 @@ Synopsis
     
     The ORIGIN frame is only usable by a server.  If this function is
     invoked with client side session, this function returns
-    :macro:`NGHTTP2_ERR_INVALID_STATE`.
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`.
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory
-    :macro:`NGHTTP2_ERR_INVALID_STATE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
         The function is called from client side session.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         There are too many origins, or an origin is too large to fit
         into a default frame payload.
index e54ef25..8237339 100644 (file)
@@ -16,10 +16,10 @@ Synopsis
     
     The *flags* is bitwise OR of 0 or more of the following value.
     
-    * :macro:`NGHTTP2_FLAG_ACK`
+    * :macro:`nghttp2_flag.NGHTTP2_FLAG_ACK`
     
     Unless `nghttp2_option_set_no_auto_ping_ack()` is used, the *flags*
-    should be :macro:`NGHTTP2_FLAG_NONE`.
+    should be :macro:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
     
     If the *opaque_data* is non ``NULL``, then it should point to the 8
     bytes array of memory to specify opaque data to send with PING
@@ -29,5 +29,5 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index 2fda48a..12a3434 100644 (file)
@@ -14,7 +14,7 @@ Synopsis
     to the priority specification *pri_spec*.
     
     The *flags* is currently ignored and should be
-    :macro:`NGHTTP2_FLAG_NONE`.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
     
     The *pri_spec* is priority specification of this request.  ``NULL``
     is not allowed for this function. To specify the priority, use
@@ -22,16 +22,17 @@ Synopsis
     members.
     
     The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
-    :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight`` is
-    strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
+    :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight``
+    is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
     :macro:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
-    :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`.
+    :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
+    :macro:`NGHTTP2_MAX_WEIGHT`.
     
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *stream_id* is 0; or the *pri_spec* is NULL; or trying to
         depend on itself.
index 9b4c974..c912e01 100644 (file)
@@ -27,12 +27,12 @@ Synopsis
     This function creates copies of all name/value pairs in *nva*.  It
     also lower-cases all names in *nva*.  The order of elements in
     *nva* is preserved.  For header fields with
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
-    and value are not copied respectively.  With
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
-    pass header field name in lowercase.  The application should
-    maintain the references to them until
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+    header field name and value are not copied respectively.  With
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+    is responsible to pass header field name in lowercase.  The
+    application should maintain the references to them until
     :type:`nghttp2_on_frame_send_callback` or
     :type:`nghttp2_on_frame_not_send_callback` is called.
     
@@ -51,18 +51,18 @@ Synopsis
     This function returns assigned promised stream ID if it succeeds,
     or one of the following negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_PROTO`
+    :macro:`nghttp2_error.NGHTTP2_ERR_PROTO`
         This function was invoked when *session* is initialized as
         client.
-    :macro:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
         No stream ID is available because maximum stream ID was
         reached.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *stream_id* is 0; The *stream_id* does not designate stream
         that peer initiated.
-    :macro:`NGHTTP2_ERR_STREAM_CLOSED`
+    :macro:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED`
         The stream was already closed; or the *stream_id* is invalid.
     
     .. warning::
index c7e229f..92f2c26 100644 (file)
@@ -19,10 +19,11 @@ Synopsis
     this function will copy its data members.
     
     The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
-    :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight`` is
-    strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
+    :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight``
+    is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
     :macro:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
-    :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`.
+    :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
+    :macro:`NGHTTP2_MAX_WEIGHT`.
     
     The *nva* is an array of name/value pair :type:`nghttp2_nv` with
     *nvlen* elements.  The application is responsible to include
@@ -33,12 +34,12 @@ Synopsis
     This function creates copies of all name/value pairs in *nva*.  It
     also lower-cases all names in *nva*.  The order of elements in
     *nva* is preserved.  For header fields with
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
-    and value are not copied respectively.  With
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
-    pass header field name in lowercase.  The application should
-    maintain the references to them until
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+    header field name and value are not copied respectively.  With
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+    is responsible to pass header field name in lowercase.  The
+    application should maintain the references to them until
     :type:`nghttp2_on_frame_send_callback` or
     :type:`nghttp2_on_frame_not_send_callback` is called.
     
@@ -60,15 +61,15 @@ Synopsis
     This function returns assigned stream ID if it succeeds, or one of
     the following negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
         No stream ID is available because maximum stream ID was
         reached.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         Trying to depend on itself (new stream ID equals
         ``pri_spec->stream_id``).
-    :macro:`NGHTTP2_ERR_PROTO`
+    :macro:`nghttp2_error.NGHTTP2_ERR_PROTO`
         The *session* is server session.
     
     .. warning::
index 1cc0412..58ae349 100644 (file)
@@ -22,12 +22,12 @@ Synopsis
     This function creates copies of all name/value pairs in *nva*.  It
     also lower-cases all names in *nva*.  The order of elements in
     *nva* is preserved.  For header fields with
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
-    and value are not copied respectively.  With
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
-    pass header field name in lowercase.  The application should
-    maintain the references to them until
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+    header field name and value are not copied respectively.  With
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+    is responsible to pass header field name in lowercase.  The
+    application should maintain the references to them until
     :type:`nghttp2_on_frame_send_callback` or
     :type:`nghttp2_on_frame_not_send_callback` is called.
     
@@ -53,16 +53,16 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *stream_id* is 0.
-    :macro:`NGHTTP2_ERR_DATA_EXIST`
+    :macro:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
         DATA or HEADERS has been already submitted and not fully
         processed yet.  Normally, this does not happen, but when
         application wrongly calls `nghttp2_submit_response()` twice,
         this may happen.
-    :macro:`NGHTTP2_ERR_PROTO`
+    :macro:`nghttp2_error.NGHTTP2_ERR_PROTO`
         The *session* is client session.
     
     .. warning::
index a179424..261f158 100644 (file)
@@ -16,12 +16,12 @@ Synopsis
     The pre-defined error code is one of :macro:`nghttp2_error_code`.
     
     The *flags* is currently ignored and should be
-    :macro:`NGHTTP2_FLAG_NONE`.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
     
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *stream_id* is 0.
index 36cbdf9..f28369a 100644 (file)
@@ -15,7 +15,7 @@ Synopsis
     indicates the number of :type:`nghttp2_settings_entry`.
     
     The *flags* is currently ignored and should be
-    :macro:`NGHTTP2_FLAG_NONE`.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
     
     This function does not take ownership of the *iv*.  This function
     copies all the elements in the *iv*.
@@ -24,14 +24,15 @@ Synopsis
     size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE,
     RST_STREAM is issued against such a stream.
     
-    SETTINGS with :macro:`NGHTTP2_FLAG_ACK` is automatically submitted
-    by the library and application could not send it at its will.
+    SETTINGS with :macro:`nghttp2_flag.NGHTTP2_FLAG_ACK` is
+    automatically submitted by the library and application could not
+    send it at its will.
     
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *iv* contains invalid value (e.g., initial window size
         strictly greater than (1 << 31) - 1.
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index d6c28b8..37d47f9 100644 (file)
@@ -15,7 +15,7 @@ Synopsis
     
     This function is only usable for server.  If this function is
     called with client side session, this function returns
-    :macro:`NGHTTP2_ERR_INVALID_STATE`.
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`.
     
     To gracefully shutdown HTTP/2 session, server should call this
     function to send GOAWAY with last_stream_id (1u << 31) - 1.  And
@@ -37,7 +37,7 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_STATE`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
         The *session* is initialized as client.
index fa27688..cf3b9b3 100644 (file)
@@ -19,12 +19,12 @@ Synopsis
     This function creates copies of all name/value pairs in *nva*.  It
     also lower-cases all names in *nva*.  The order of elements in
     *nva* is preserved.  For header fields with
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
-    and value are not copied respectively.  With
-    :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
-    pass header field name in lowercase.  The application should
-    maintain the references to them until
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+    header field name and value are not copied respectively.  With
+    :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+    is responsible to pass header field name in lowercase.  The
+    application should maintain the references to them until
     :type:`nghttp2_on_frame_send_callback` or
     :type:`nghttp2_on_frame_not_send_callback` is called.
     
@@ -36,16 +36,16 @@ Synopsis
     *nva* will be sent as response headers, which will result in error.
     
     This function has the same effect with `nghttp2_submit_headers()`,
-    with flags = :macro:`NGHTTP2_FLAG_END_STREAM` and both pri_spec and
-    stream_user_data to NULL.
+    with flags = :macro:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` and both
+    pri_spec and stream_user_data to NULL.
     
     To submit trailer fields after `nghttp2_submit_response()` is
     called, the application has to specify
     :type:`nghttp2_data_provider` to `nghttp2_submit_response()`.
     Inside of :type:`nghttp2_data_source_read_callback`, when setting
-    :macro:`NGHTTP2_DATA_FLAG_EOF`, also set
-    :macro:`NGHTTP2_DATA_FLAG_NO_END_STREAM`.  After that, the
-    application can send trailer fields using
+    :macro:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF`, also set
+    :macro:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM`.  After
+    that, the application can send trailer fields using
     `nghttp2_submit_trailer()`.  `nghttp2_submit_trailer()` can be used
     inside :type:`nghttp2_data_source_read_callback`.
     
@@ -53,7 +53,7 @@ Synopsis
     Otherwise, this function returns 0 if it succeeds, or one of the
     following negative error codes:
     
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
-    :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
+    :macro:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
         The *stream_id* is 0.
index 50fd1e3..f3792e0 100644 (file)
@@ -13,7 +13,7 @@ Synopsis
     Submits WINDOW_UPDATE frame.
     
     The *flags* is currently ignored and should be
-    :macro:`NGHTTP2_FLAG_NONE`.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
     
     The *stream_id* is the stream ID to send this WINDOW_UPDATE.  To
     send connection level WINDOW_UPDATE, specify 0 to *stream_id*.
@@ -40,7 +40,7 @@ Synopsis
     This function returns 0 if it succeeds, or one of the following
     negative error codes:
     
-    :macro:`NGHTTP2_ERR_FLOW_CONTROL`
+    :macro:`nghttp2_error.NGHTTP2_ERR_FLOW_CONTROL`
         The local window size overflow or gets negative.
-    :macro:`NGHTTP2_ERR_NOMEM`
+    :macro:`nghttp2_error.NGHTTP2_ERR_NOMEM`
         Out of memory.
index fb46e54..25d4f49 100644 (file)
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "NGHTTPD" "1" "Jun 02, 2020" "1.41.0" "nghttp2"
+.TH "NGHTTPD" "1" "Oct 19, 2021" "1.46.0" "nghttp2"
 .SH NAME
 nghttpd \- HTTP/2 server
 .
index c101661..a328ba2 100644 (file)
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "NGHTTPX" "1" "Jun 02, 2020" "1.41.0" "nghttp2"
+.TH "NGHTTPX" "1" "Oct 19, 2021" "1.46.0" "nghttp2"
 .SH NAME
 nghttpx \- HTTP/2 proxy
 .
@@ -35,7 +35,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
 \fBnghttpx\fP [OPTIONS]... [<PRIVATE_KEY> <CERT>]
 .SH DESCRIPTION
 .sp
-A reverse proxy for HTTP/2, and HTTP/1.
+A reverse proxy for HTTP/3, HTTP/2, and HTTP/1.
 .INDENT 0.0
 .TP
 .B <PRIVATE_KEY>
@@ -140,12 +140,13 @@ parameters       are:      "proto=<PROTO>",       "tls",
 "affinity=<METHOD>",    "dns",    "redirect\-if\-not\-tls",
 "upgrade\-scheme",                        "mruby=<PATH>",
 "read\-timeout=<DURATION>",   "write\-timeout=<DURATION>",
-"group=<GROUP>",  "group\-weight=<N>", and  "weight=<N>".
-The  parameter  consists   of  keyword,  and  optionally
-followed by  "=" and value.  For  example, the parameter
-"proto=h2"  consists of  the keyword  "proto" and  value
-"h2".  The parameter "tls" consists of the keyword "tls"
-without value.  Each parameter is described as follows.
+"group=<GROUP>",  "group\-weight=<N>", "weight=<N>",  and
+"dnf".    The  parameter   consists   of  keyword,   and
+optionally followed by "="  and value.  For example, the
+parameter "proto=h2" consists of the keyword "proto" and
+value "h2".  The parameter "tls" consists of the keyword
+"tls"  without value.   Each parameter  is described  as
+follows.
 .sp
 The backend application protocol  can be specified using
 optional  "proto"   parameter,  and   in  the   form  of
@@ -276,9 +277,19 @@ weight  than weight  2.  If  this parameter  is omitted,
 weight  becomes  1.   "weight"  is  ignored  if  session
 affinity is enabled.
 .sp
+If "dnf" parameter is  specified, an incoming request is
+not forwarded to a backend  and just consumed along with
+the  request body  (actually a  backend server  never be
+contacted).  It  is expected  that the HTTP  response is
+generated by mruby  script (see "mruby=<PATH>" parameter
+above).  "dnf" is an abbreviation of "do not forward".
+.sp
 Since ";" and ":" are  used as delimiter, <PATTERN> must
-not  contain these  characters.  Since  ";" has  special
-meaning in shell, the option value must be quoted.
+not contain  these characters.  In order  to include ":"
+in  <PATTERN>,  one  has  to  specify  "%3A"  (which  is
+percent\-encoded  from of  ":") instead.   Since ";"  has
+special  meaning  in shell,  the  option  value must  be
+quoted.
 .sp
 Default: \fB127.0.0.1,80\fP
 .UNINDENT
@@ -320,6 +331,12 @@ To accept  PROXY protocol  version 1  and 2  on frontend
 connection,  specify  "proxyproto" parameter.   This  is
 disabled by default.
 .sp
+To  receive   HTTP/3  (QUIC)  traffic,   specify  "quic"
+parameter.  It  makes nghttpx listen on  UDP port rather
+than  TCP   port.   UNIX   domain  socket,   "api",  and
+"healthmon"  parameters  cannot   be  used  with  "quic"
+parameter.
+.sp
 Default: \fB*,3000\fP
 .UNINDENT
 .INDENT 0.0
@@ -486,6 +503,15 @@ Default: \fB0\fP
 .UNINDENT
 .INDENT 0.0
 .TP
+.B \-\-rlimit\-memlock=<N>
+Set maximum number of bytes of memory that may be locked
+into  RAM.  If  0 is  given,  nghttpx does  not set  the
+limit.
+.sp
+Default: \fB0\fP
+.UNINDENT
+.INDENT 0.0
+.TP
 .B \-\-backend\-request\-buffer=<SIZE>
 Set buffer size used to store backend request.
 .sp
@@ -525,6 +551,13 @@ Default: \fB3m\fP
 .UNINDENT
 .INDENT 0.0
 .TP
+.B \-\-frontend\-http3\-read\-timeout=<DURATION>
+Specify read timeout for HTTP/3 frontend connection.
+.sp
+Default: \fB3m\fP
+.UNINDENT
+.INDENT 0.0
+.TP
 .B \-\-frontend\-read\-timeout=<DURATION>
 Specify read timeout for HTTP/1.1 frontend connection.
 .sp
@@ -1003,19 +1036,19 @@ Default: \fB1s\fP
 .UNINDENT
 .INDENT 0.0
 .TP
-.B \-\-no\-http2\-cipher\-black\-list
-Allow  black  listed  cipher suite  on  frontend  HTTP/2
+.B \-\-no\-http2\-cipher\-block\-list
+Allow  block  listed  cipher suite  on  frontend  HTTP/2
 connection.                                          See
 \fI\%https://tools.ietf.org/html/rfc7540#appendix\-A\fP  for  the
-complete HTTP/2 cipher suites black list.
+complete HTTP/2 cipher suites block list.
 .UNINDENT
 .INDENT 0.0
 .TP
-.B \-\-client\-no\-http2\-cipher\-black\-list
-Allow  black  listed  cipher  suite  on  backend  HTTP/2
+.B \-\-client\-no\-http2\-cipher\-block\-list
+Allow  block  listed  cipher  suite  on  backend  HTTP/2
 connection.                                          See
 \fI\%https://tools.ietf.org/html/rfc7540#appendix\-A\fP  for  the
-complete HTTP/2 cipher suites black list.
+complete HTTP/2 cipher suites block list.
 .UNINDENT
 .INDENT 0.0
 .TP
@@ -1040,9 +1073,9 @@ in hex.  An  empty line, and line which  starts with \(aq#\(aq
 are skipped.  The default  enabled cipher list might not
 contain any PSK cipher suite.  In that case, desired PSK
 cipher suites  must be  enabled using  \fI\%\-\-ciphers\fP option.
-The  desired PSK  cipher suite  may be  black listed  by
+The  desired PSK  cipher suite  may be  block listed  by
 HTTP/2.   To  use  those   cipher  suites  with  HTTP/2,
-consider  to  use  \fI\%\-\-no\-http2\-cipher\-black\-list\fP  option.
+consider  to  use  \fI\%\-\-no\-http2\-cipher\-block\-list\fP  option.
 But be aware its implications.
 .UNINDENT
 .INDENT 0.0
@@ -1057,20 +1090,21 @@ The first identity and  secret pair encountered is used.
 The default  enabled cipher  list might not  contain any
 PSK  cipher suite.   In  that case,  desired PSK  cipher
 suites  must be  enabled using  \fI\%\-\-client\-ciphers\fP option.
-The  desired PSK  cipher suite  may be  black listed  by
+The  desired PSK  cipher suite  may be  block listed  by
 HTTP/2.   To  use  those   cipher  suites  with  HTTP/2,
-consider   to  use   \fI\%\-\-client\-no\-http2\-cipher\-black\-list\fP
+consider   to  use   \fI\%\-\-client\-no\-http2\-cipher\-block\-list\fP
 option.  But be aware its implications.
 .UNINDENT
 .INDENT 0.0
 .TP
 .B \-\-tls\-no\-postpone\-early\-data
-By default,  nghttpx postpones forwarding  HTTP requests
-sent in early data, including those sent in partially in
-it, until TLS handshake finishes.  If all backend server
-recognizes "Early\-Data" header  field, using this option
-makes nghttpx  not postpone  forwarding request  and get
-full potential of 0\-RTT data.
+By  default,   except  for  QUIC   connections,  nghttpx
+postpones forwarding  HTTP requests sent in  early data,
+including  those  sent in  partially  in  it, until  TLS
+handshake  finishes.  If  all backend  server recognizes
+"Early\-Data"  header  field,  using  this  option  makes
+nghttpx  not postpone  forwarding request  and get  full
+potential of 0\-RTT data.
 .UNINDENT
 .INDENT 0.0
 .TP
@@ -1324,6 +1358,18 @@ request.  "\-" if backend host is not available.
 .IP \(bu 2
 $backend_port:  backend  port   used  to  fulfill  the
 request.  "\-" if backend host is not available.
+.IP \(bu 2
+$method: HTTP method
+.IP \(bu 2
+$path:  Request  path  including query.   For  CONNECT
+request, authority is recorded.
+.IP \(bu 2
+$path_without_query:  $path   up  to  the   first  \(aq?\(aq
+character.    For   CONNECT  request,   authority   is
+recorded.
+.IP \(bu 2
+$protocol_version:   HTTP  version   (e.g.,  HTTP/1.1,
+HTTP/2)
 .UNINDENT
 .sp
 The  variable  can  be  enclosed  by  "{"  and  "}"  for
@@ -1463,13 +1509,21 @@ not be altered regardless of this option.
 .UNINDENT
 .INDENT 0.0
 .TP
-.B \-\-altsvc=<PROTOID,PORT[,HOST,[ORIGIN]]>
+.B \-\-altsvc=<PROTOID,PORT[,HOST,[ORIGIN[,PARAMS]]]>
 Specify   protocol  ID,   port,  host   and  origin   of
-alternative service.  <HOST>  and <ORIGIN> are optional.
-They  are advertised  in  alt\-svc header  field only  in
-HTTP/1.1  frontend.  This  option can  be used  multiple
-times   to   specify  multiple   alternative   services.
-Example: \fI\%\-\-altsvc\fP=h2,443
+alternative service.  <HOST>,  <ORIGIN> and <PARAMS> are
+optional.   Empty <HOST>  and <ORIGIN>  are allowed  and
+they  are treated  as  nothing is  specified.  They  are
+advertised  in alt\-svc  header  field  only in  HTTP/1.1
+frontend.   This option  can be  used multiple  times to
+specify multiple alternative services.
+Example: \fI\%\-\-altsvc\fP="h2,443,,,ma=3600; persist=1\(aq
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-http2\-altsvc=<PROTOID,PORT[,HOST,[ORIGIN[,PARAMS]]]>
+Just like \fI\%\-\-altsvc\fP option, but  this altsvc is only sent
+in HTTP/2 frontend.
 .UNINDENT
 .INDENT 0.0
 .TP
@@ -1654,12 +1708,39 @@ be used to drop root privileges.
 .B \-\-single\-process
 Run this program in a  single process mode for debugging
 purpose.  Without this option,  nghttpx creates at least
-2  processes:  master  and worker  processes.   If  this
-option is  used, master  and worker  are unified  into a
-single process.  nghttpx still spawns additional process
-if neverbleed is used.  In  the single process mode, the
+2 processes: main and  worker processes.  If this option
+is  used, main  and  worker are  unified  into a  single
+process.   nghttpx still  spawns  additional process  if
+neverbleed  is used.   In the  single process  mode, the
 signal handling feature is disabled.
 .UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-max\-worker\-processes=<N>
+The maximum number of  worker processes.  nghttpx spawns
+new worker  process when  it reloads  its configuration.
+The previous worker  process enters graceful termination
+period and will terminate  when it finishes handling the
+existing    connections.     However,    if    reloading
+configurations  happen   very  frequently,   the  worker
+processes might be piled up if they take a bit long time
+to finish  the existing connections.  With  this option,
+if  the number  of  worker processes  exceeds the  given
+value,   the  oldest   worker   process  is   terminated
+immediately.  Specifying 0 means no  limit and it is the
+default behaviour.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-worker\-process\-grace\-shutdown\-period=<DURATION>
+Maximum  period  for  a   worker  process  to  terminate
+gracefully.  When  a worker  process enters  in graceful
+shutdown   period  (e.g.,   when  nghttpx   reloads  its
+configuration)  and  it  does not  finish  handling  the
+existing connections in the given  period of time, it is
+immediately terminated.  Specifying 0 means no limit and
+it is the default behaviour.
+.UNINDENT
 .SS Scripting
 .INDENT 0.0
 .TP
@@ -1673,6 +1754,160 @@ Ignore mruby compile error  for per\-pattern mruby script
 file.  If error  occurred, it is treated as  if no mruby
 file were specified for the pattern.
 .UNINDENT
+.SS HTTP/3 and QUIC
+.INDENT 0.0
+.TP
+.B \-\-frontend\-quic\-idle\-timeout=<DURATION>
+Specify an idle timeout for QUIC connection.
+.sp
+Default: \fB30s\fP
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-quic\-debug\-log
+Output QUIC debug log to \fI/dev/stderr.\fP
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-quic\-bpf\-program\-file=<PATH>
+Specify a path to  eBPF program file reuseport_kern.o to
+direct  an  incoming  QUIC  UDP datagram  to  a  correct
+socket.
+.sp
+Default: \fB/usr/local/lib/nghttp2/reuseport_kern.o\fP
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-quic\-early\-data
+Enable early data on frontend QUIC connections.  nghttpx
+sends "Early\-Data" header field to a backend server if a
+request is received in early  data and handshake has not
+finished.  All backend servers should deal with possibly
+replayed requests.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-quic\-qlog\-dir=<DIR>
+Specify a  directory where  a qlog  file is  written for
+frontend QUIC  connections.  A qlog file  is created per
+each QUIC  connection.  The  file name is  ISO8601 basic
+format, followed by "\-", server Source Connection ID and
+".qlog".
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-quic\-require\-token
+Require an address validation  token for a frontend QUIC
+connection.   Server sends  a token  in Retry  packet or
+NEW_TOKEN frame in the previous connection.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-quic\-congestion\-controller=<CC>
+Specify a congestion controller algorithm for a frontend
+QUIC  connection.   <CC>  should be  either  "cubic"  or
+"bbr".
+.sp
+Default: \fBcubic\fP
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-quic\-secret\-file=<PATH>
+Path to file that contains secure random data to be used
+as QUIC keying materials.  It is used to derive keys for
+encrypting tokens and Connection IDs.  It is not used to
+encrypt  QUIC  packets.  Each  line  of  this file  must
+contain  exactly  136  bytes  hex\-encoded  string  (when
+decoded the byte string is  68 bytes long).  The first 2
+bits of  decoded byte  string are  used to  identify the
+keying material.  An  empty line or a  line which starts
+\(aq#\(aq  is ignored.   The file  can contain  more than  one
+keying materials.  Because the  identifier is 2 bits, at
+most 4 keying materials are  read and the remaining data
+is discarded.  The first keying  material in the file is
+primarily  used for  encryption and  decryption for  new
+connection.  The other ones are used to decrypt data for
+the  existing connections.   Specifying multiple  keying
+materials enables  key rotation.   Please note  that key
+rotation  does  not  occur automatically.   User  should
+update  files  or  change  options  values  and  restart
+nghttpx gracefully.   If opening  or reading  given file
+fails, all loaded keying  materials are discarded and it
+is treated as if none of  this option is given.  If this
+option is not  given or an error  occurred while opening
+or  reading  a  file,  a keying  material  is  generated
+internally on startup and reload.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-quic\-server\-id=<HEXSTRING>
+Specify server  ID encoded in Connection  ID to identify
+this  particular  server  instance.   Connection  ID  is
+encrypted and  this part is  not visible in  public.  It
+must be 4  bytes long and must be encoded  in hex string
+(which is 8  bytes long).  If this option  is omitted, a
+random   server  ID   is   generated   on  startup   and
+configuration reload.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-quic\-initial\-rtt=<DURATION>
+Specify the initial RTT of the frontend QUIC connection.
+.sp
+Default: \fB333ms\fP
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-no\-quic\-bpf
+Disable eBPF.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-http3\-window\-size=<SIZE>
+Sets  the  per\-stream  initial  window  size  of  HTTP/3
+frontend connection.
+.sp
+Default: \fB256K\fP
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-http3\-connection\-window\-size=<SIZE>
+Sets the  per\-connection window size of  HTTP/3 frontend
+connection.
+.sp
+Default: \fB1M\fP
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-http3\-max\-window\-size=<SIZE>
+Sets  the  maximum  per\-stream  window  size  of  HTTP/3
+frontend connection.  The window  size is adjusted based
+on the receiving rate of stream data.  The initial value
+is the  value specified  by \fI\%\-\-frontend\-http3\-window\-size\fP
+and the window size grows up to <SIZE> bytes.
+.sp
+Default: \fB6M\fP
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-http3\-max\-connection\-window\-size=<SIZE>
+Sets the  maximum per\-connection  window size  of HTTP/3
+frontend connection.  The window  size is adjusted based
+on the receiving rate of stream data.  The initial value
+is         the         value        specified         by
+\fI\%\-\-frontend\-http3\-connection\-window\-size\fP  and the  window
+size grows up to <SIZE> bytes.
+.sp
+Default: \fB8M\fP
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-frontend\-http3\-max\-concurrent\-streams=<N>
+Set the maximum number of  the concurrent streams in one
+frontend HTTP/3 connection.
+.sp
+Default: \fB100\fP
+.UNINDENT
 .SS Misc
 .INDENT 0.0
 .TP
@@ -1769,15 +2004,15 @@ Error log is written to stderr by default.  It can be configured
 using \fI\%\-\-errorlog\-file\fP\&.  The format of log message is as
 follows:
 .sp
-<datetime> <master\-pid> <current\-pid> <thread\-id> <level> (<filename>:<line>) <msg>
+<datetime> <main\-pid> <current\-pid> <thread\-id> <level> (<filename>:<line>) <msg>
 .INDENT 7.0
 .TP
 .B <datetime>
 It is a combination of date and time when the log is written.  It
 is in ISO 8601 format.
 .TP
-.B <master\-pid>
-It is a master process ID.
+.B <main\-pid>
+It is a main process ID.
 .TP
 .B <current\-pid>
 It is a process ID which writes this log.
@@ -1813,15 +2048,15 @@ SIGUSR2
 .INDENT 3.5
 Fork and execute nghttpx.  It will execute the binary in the same
 path with same command\-line arguments and environment variables.  As
-of nghttpx version 1.20.0, the new master process sends SIGQUIT to
-the original master process when it is ready to serve requests.  For
-the earlier versions of nghttpx, user has to send SIGQUIT to the
-original master process.
+of nghttpx version 1.20.0, the new main process sends SIGQUIT to the
+original main process when it is ready to serve requests.  For the
+earlier versions of nghttpx, user has to send SIGQUIT to the
+original main process.
 .sp
 The difference between SIGUSR2 (+ SIGQUIT) and SIGHUP is that former
-is usually used to execute new binary, and the master process is
-newly spawned.  On the other hand, the latter just reloads
-configuration file, and the same master process continues to exist.
+is usually used to execute new binary, and the main process is newly
+spawned.  On the other hand, the latter just reloads configuration
+file, and the same main process continues to exist.
 .UNINDENT
 .UNINDENT
 .sp
@@ -1830,16 +2065,16 @@ configuration file, and the same master process continues to exist.
 .INDENT 3.5
 nghttpx consists of multiple processes: one process for processing
 these signals, and another one for processing requests.  The former
-spawns the latter.  The former is called master process, and the
+spawns the latter.  The former is called main process, and the
 latter is called worker process.  If neverbleed is enabled, the
 worker process spawns neverbleed daemon process which does RSA key
-processing.  The above signal must be sent to the master process.
-If the other processes received one of them, it is ignored.  This
+processing.  The above signal must be sent to the main process.  If
+the other processes received one of them, it is ignored.  This
 behaviour of these processes may change in the future release.  In
-other words, in the future release, the processes other than master
+other words, in the future release, the processes other than main
 process may terminate upon the reception of these signals.
 Therefore these signals should not be sent to the processes other
-than master process.
+than main process.
 .UNINDENT
 .UNINDENT
 .SH SERVER PUSH
index 5259eb9..6037406 100644 (file)
@@ -14,7 +14,7 @@ SYNOPSIS
 DESCRIPTION
 -----------
 
-A reverse proxy for HTTP/2, and HTTP/1.
+A reverse proxy for HTTP/3, HTTP/2, and HTTP/1.
 
 .. describe:: <PRIVATE_KEY>
 
@@ -124,12 +124,13 @@ Connections
     "affinity=<METHOD>",    "dns",    "redirect-if-not-tls",
     "upgrade-scheme",                        "mruby=<PATH>",
     "read-timeout=<DURATION>",   "write-timeout=<DURATION>",
-    "group=<GROUP>",  "group-weight=<N>", and  "weight=<N>".
-    The  parameter  consists   of  keyword,  and  optionally
-    followed by  "=" and value.  For  example, the parameter
-    "proto=h2"  consists of  the keyword  "proto" and  value
-    "h2".  The parameter "tls" consists of the keyword "tls"
-    without value.  Each parameter is described as follows.
+    "group=<GROUP>",  "group-weight=<N>", "weight=<N>",  and
+    "dnf".    The  parameter   consists   of  keyword,   and
+    optionally followed by "="  and value.  For example, the
+    parameter "proto=h2" consists of the keyword "proto" and
+    value "h2".  The parameter "tls" consists of the keyword
+    "tls"  without value.   Each parameter  is described  as
+    follows.
 
     The backend application protocol  can be specified using
     optional  "proto"   parameter,  and   in  the   form  of
@@ -260,9 +261,19 @@ Connections
     weight  becomes  1.   "weight"  is  ignored  if  session
     affinity is enabled.
 
+    If "dnf" parameter is  specified, an incoming request is
+    not forwarded to a backend  and just consumed along with
+    the  request body  (actually a  backend server  never be
+    contacted).  It  is expected  that the HTTP  response is
+    generated by mruby  script (see "mruby=<PATH>" parameter
+    above).  "dnf" is an abbreviation of "do not forward".
+
     Since ";" and ":" are  used as delimiter, <PATTERN> must
-    not  contain these  characters.  Since  ";" has  special
-    meaning in shell, the option value must be quoted.
+    not contain  these characters.  In order  to include ":"
+    in  <PATTERN>,  one  has  to  specify  "%3A"  (which  is
+    percent-encoded  from of  ":") instead.   Since ";"  has
+    special  meaning  in shell,  the  option  value must  be
+    quoted.
 
 
     Default: ``127.0.0.1,80``
@@ -304,6 +315,12 @@ Connections
     connection,  specify  "proxyproto" parameter.   This  is
     disabled by default.
 
+    To  receive   HTTP/3  (QUIC)  traffic,   specify  "quic"
+    parameter.  It  makes nghttpx listen on  UDP port rather
+    than  TCP   port.   UNIX   domain  socket,   "api",  and
+    "healthmon"  parameters  cannot   be  used  with  "quic"
+    parameter.
+
 
     Default: ``*,3000``
 
@@ -455,6 +472,14 @@ Performance
 
     Default: ``0``
 
+.. option:: --rlimit-memlock=<N>
+
+    Set maximum number of bytes of memory that may be locked
+    into  RAM.  If  0 is  given,  nghttpx does  not set  the
+    limit.
+
+    Default: ``0``
+
 .. option:: --backend-request-buffer=<SIZE>
 
     Set buffer size used to store backend request.
@@ -492,6 +517,12 @@ Timeout
 
     Default: ``3m``
 
+.. option:: --frontend-http3-read-timeout=<DURATION>
+
+    Specify read timeout for HTTP/3 frontend connection.
+
+    Default: ``3m``
+
 .. option:: --frontend-read-timeout=<DURATION>
 
     Specify read timeout for HTTP/1.1 frontend connection.
@@ -922,19 +953,19 @@ SSL/TLS
 
     Default: ``1s``
 
-.. option:: --no-http2-cipher-black-list
+.. option:: --no-http2-cipher-block-list
 
-    Allow  black  listed  cipher suite  on  frontend  HTTP/2
+    Allow  block  listed  cipher suite  on  frontend  HTTP/2
     connection.                                          See
     https://tools.ietf.org/html/rfc7540#appendix-A  for  the
-    complete HTTP/2 cipher suites black list.
+    complete HTTP/2 cipher suites block list.
 
-.. option:: --client-no-http2-cipher-black-list
+.. option:: --client-no-http2-cipher-block-list
 
-    Allow  black  listed  cipher  suite  on  backend  HTTP/2
+    Allow  block  listed  cipher  suite  on  backend  HTTP/2
     connection.                                          See
     https://tools.ietf.org/html/rfc7540#appendix-A  for  the
-    complete HTTP/2 cipher suites black list.
+    complete HTTP/2 cipher suites block list.
 
 .. option:: --tls-sct-dir=<DIR>
 
@@ -957,9 +988,9 @@ SSL/TLS
     are skipped.  The default  enabled cipher list might not
     contain any PSK cipher suite.  In that case, desired PSK
     cipher suites  must be  enabled using  :option:`--ciphers` option.
-    The  desired PSK  cipher suite  may be  black listed  by
+    The  desired PSK  cipher suite  may be  block listed  by
     HTTP/2.   To  use  those   cipher  suites  with  HTTP/2,
-    consider  to  use  :option:`--no-http2-cipher-black-list`  option.
+    consider  to  use  :option:`--no-http2-cipher-block-list`  option.
     But be aware its implications.
 
 .. option:: --client-psk-secrets=<PATH>
@@ -973,19 +1004,20 @@ SSL/TLS
     The default  enabled cipher  list might not  contain any
     PSK  cipher suite.   In  that case,  desired PSK  cipher
     suites  must be  enabled using  :option:`--client-ciphers` option.
-    The  desired PSK  cipher suite  may be  black listed  by
+    The  desired PSK  cipher suite  may be  block listed  by
     HTTP/2.   To  use  those   cipher  suites  with  HTTP/2,
-    consider   to  use   :option:`--client-no-http2-cipher-black-list`
+    consider   to  use   :option:`--client-no-http2-cipher-block-list`
     option.  But be aware its implications.
 
 .. option:: --tls-no-postpone-early-data
 
-    By default,  nghttpx postpones forwarding  HTTP requests
-    sent in early data, including those sent in partially in
-    it, until TLS handshake finishes.  If all backend server
-    recognizes "Early-Data" header  field, using this option
-    makes nghttpx  not postpone  forwarding request  and get
-    full potential of 0-RTT data.
+    By  default,   except  for  QUIC   connections,  nghttpx
+    postpones forwarding  HTTP requests sent in  early data,
+    including  those  sent in  partially  in  it, until  TLS
+    handshake  finishes.  If  all backend  server recognizes
+    "Early-Data"  header  field,  using  this  option  makes
+    nghttpx  not postpone  forwarding request  and get  full
+    potential of 0-RTT data.
 
 .. option:: --tls-max-early-data=<SIZE>
 
@@ -1203,6 +1235,14 @@ Logging
       request.  "-" if backend host is not available.
     * $backend_port:  backend  port   used  to  fulfill  the
       request.  "-" if backend host is not available.
+    * $method: HTTP method
+    * $path:  Request  path  including query.   For  CONNECT
+      request, authority is recorded.
+    * $path_without_query:  $path   up  to  the   first  '?'
+      character.    For   CONNECT  request,   authority   is
+      recorded.
+    * $protocol_version:   HTTP  version   (e.g.,  HTTP/1.1,
+      HTTP/2)
 
     The  variable  can  be  enclosed  by  "{"  and  "}"  for
     disambiguation (e.g., ${remote_addr}).
@@ -1327,14 +1367,21 @@ HTTP
     mode.  When  :option:`--http2-proxy` is  used, these  headers will
     not be altered regardless of this option.
 
-.. option:: --altsvc=<PROTOID,PORT[,HOST,[ORIGIN]]>
+.. option:: --altsvc=<PROTOID,PORT[,HOST,[ORIGIN[,PARAMS]]]>
 
     Specify   protocol  ID,   port,  host   and  origin   of
-    alternative service.  <HOST>  and <ORIGIN> are optional.
-    They  are advertised  in  alt-svc header  field only  in
-    HTTP/1.1  frontend.  This  option can  be used  multiple
-    times   to   specify  multiple   alternative   services.
-    Example: :option:`--altsvc`\=h2,443
+    alternative service.  <HOST>,  <ORIGIN> and <PARAMS> are
+    optional.   Empty <HOST>  and <ORIGIN>  are allowed  and
+    they  are treated  as  nothing is  specified.  They  are
+    advertised  in alt-svc  header  field  only in  HTTP/1.1
+    frontend.   This option  can be  used multiple  times to
+    specify multiple alternative services.
+    Example: :option:`--altsvc`\="h2,443,,,ma=3600; persist=1'
+
+.. option:: --http2-altsvc=<PROTOID,PORT[,HOST,[ORIGIN[,PARAMS]]]>
+
+    Just like :option:`--altsvc` option, but  this altsvc is only sent
+    in HTTP/2 frontend.
 
 .. option:: --add-request-header=<HEADER>
 
@@ -1509,12 +1556,37 @@ Process
 
     Run this program in a  single process mode for debugging
     purpose.  Without this option,  nghttpx creates at least
-    2  processes:  master  and worker  processes.   If  this
-    option is  used, master  and worker  are unified  into a
-    single process.  nghttpx still spawns additional process
-    if neverbleed is used.  In  the single process mode, the
+    2 processes: main and  worker processes.  If this option
+    is  used, main  and  worker are  unified  into a  single
+    process.   nghttpx still  spawns  additional process  if
+    neverbleed  is used.   In the  single process  mode, the
     signal handling feature is disabled.
 
+.. option:: --max-worker-processes=<N>
+
+    The maximum number of  worker processes.  nghttpx spawns
+    new worker  process when  it reloads  its configuration.
+    The previous worker  process enters graceful termination
+    period and will terminate  when it finishes handling the
+    existing    connections.     However,    if    reloading
+    configurations  happen   very  frequently,   the  worker
+    processes might be piled up if they take a bit long time
+    to finish  the existing connections.  With  this option,
+    if  the number  of  worker processes  exceeds the  given
+    value,   the  oldest   worker   process  is   terminated
+    immediately.  Specifying 0 means no  limit and it is the
+    default behaviour.
+
+.. option:: --worker-process-grace-shutdown-period=<DURATION>
+
+    Maximum  period  for  a   worker  process  to  terminate
+    gracefully.  When  a worker  process enters  in graceful
+    shutdown   period  (e.g.,   when  nghttpx   reloads  its
+    configuration)  and  it  does not  finish  handling  the
+    existing connections in the given  period of time, it is
+    immediately terminated.  Specifying 0 means no limit and
+    it is the default behaviour.
+
 
 Scripting
 ~~~~~~~~~
@@ -1530,6 +1602,147 @@ Scripting
     file were specified for the pattern.
 
 
+HTTP/3 and QUIC
+~~~~~~~~~~~~~~~
+
+.. option:: --frontend-quic-idle-timeout=<DURATION>
+
+    Specify an idle timeout for QUIC connection.
+
+    Default: ``30s``
+
+.. option:: --frontend-quic-debug-log
+
+    Output QUIC debug log to */dev/stderr.*
+
+.. option:: --quic-bpf-program-file=<PATH>
+
+    Specify a path to  eBPF program file reuseport_kern.o to
+    direct  an  incoming  QUIC  UDP datagram  to  a  correct
+    socket.
+
+    Default: ``/usr/local/lib/nghttp2/reuseport_kern.o``
+
+.. option:: --frontend-quic-early-data
+
+    Enable early data on frontend QUIC connections.  nghttpx
+    sends "Early-Data" header field to a backend server if a
+    request is received in early  data and handshake has not
+    finished.  All backend servers should deal with possibly
+    replayed requests.
+
+.. option:: --frontend-quic-qlog-dir=<DIR>
+
+    Specify a  directory where  a qlog  file is  written for
+    frontend QUIC  connections.  A qlog file  is created per
+    each QUIC  connection.  The  file name is  ISO8601 basic
+    format, followed by "-", server Source Connection ID and
+    ".qlog".
+
+.. option:: --frontend-quic-require-token
+
+    Require an address validation  token for a frontend QUIC
+    connection.   Server sends  a token  in Retry  packet or
+    NEW_TOKEN frame in the previous connection.
+
+.. option:: --frontend-quic-congestion-controller=<CC>
+
+    Specify a congestion controller algorithm for a frontend
+    QUIC  connection.   <CC>  should be  either  "cubic"  or
+    "bbr".
+
+    Default: ``cubic``
+
+.. option:: --frontend-quic-secret-file=<PATH>
+
+    Path to file that contains secure random data to be used
+    as QUIC keying materials.  It is used to derive keys for
+    encrypting tokens and Connection IDs.  It is not used to
+    encrypt  QUIC  packets.  Each  line  of  this file  must
+    contain  exactly  136  bytes  hex-encoded  string  (when
+    decoded the byte string is  68 bytes long).  The first 2
+    bits of  decoded byte  string are  used to  identify the
+    keying material.  An  empty line or a  line which starts
+    '#'  is ignored.   The file  can contain  more than  one
+    keying materials.  Because the  identifier is 2 bits, at
+    most 4 keying materials are  read and the remaining data
+    is discarded.  The first keying  material in the file is
+    primarily  used for  encryption and  decryption for  new
+    connection.  The other ones are used to decrypt data for
+    the  existing connections.   Specifying multiple  keying
+    materials enables  key rotation.   Please note  that key
+    rotation  does  not  occur automatically.   User  should
+    update  files  or  change  options  values  and  restart
+    nghttpx gracefully.   If opening  or reading  given file
+    fails, all loaded keying  materials are discarded and it
+    is treated as if none of  this option is given.  If this
+    option is not  given or an error  occurred while opening
+    or  reading  a  file,  a keying  material  is  generated
+    internally on startup and reload.
+
+.. option:: --quic-server-id=<HEXSTRING>
+
+    Specify server  ID encoded in Connection  ID to identify
+    this  particular  server  instance.   Connection  ID  is
+    encrypted and  this part is  not visible in  public.  It
+    must be 4  bytes long and must be encoded  in hex string
+    (which is 8  bytes long).  If this option  is omitted, a
+    random   server  ID   is   generated   on  startup   and
+    configuration reload.
+
+.. option:: --frontend-quic-initial-rtt=<DURATION>
+
+    Specify the initial RTT of the frontend QUIC connection.
+
+    Default: ``333ms``
+
+.. option:: --no-quic-bpf
+
+    Disable eBPF.
+
+.. option:: --frontend-http3-window-size=<SIZE>
+
+    Sets  the  per-stream  initial  window  size  of  HTTP/3
+    frontend connection.
+
+    Default: ``256K``
+
+.. option:: --frontend-http3-connection-window-size=<SIZE>
+
+    Sets the  per-connection window size of  HTTP/3 frontend
+    connection.
+
+    Default: ``1M``
+
+.. option:: --frontend-http3-max-window-size=<SIZE>
+
+    Sets  the  maximum  per-stream  window  size  of  HTTP/3
+    frontend connection.  The window  size is adjusted based
+    on the receiving rate of stream data.  The initial value
+    is the  value specified  by :option:`--frontend-http3-window-size`
+    and the window size grows up to <SIZE> bytes.
+
+    Default: ``6M``
+
+.. option:: --frontend-http3-max-connection-window-size=<SIZE>
+
+    Sets the  maximum per-connection  window size  of HTTP/3
+    frontend connection.  The window  size is adjusted based
+    on the receiving rate of stream data.  The initial value
+    is         the         value        specified         by
+    :option:`--frontend-http3-connection-window-size`  and the  window
+    size grows up to <SIZE> bytes.
+
+    Default: ``8M``
+
+.. option:: --frontend-http3-max-concurrent-streams=<N>
+
+    Set the maximum number of  the concurrent streams in one
+    frontend HTTP/3 connection.
+
+    Default: ``100``
+
+
 Misc
 ~~~~
 
@@ -1614,14 +1827,14 @@ Error log
   using :option:`--errorlog-file`.  The format of log message is as
   follows:
 
-  <datetime> <master-pid> <current-pid> <thread-id> <level> (<filename>:<line>) <msg>
+  <datetime> <main-pid> <current-pid> <thread-id> <level> (<filename>:<line>) <msg>
 
   <datetime>
     It is a combination of date and time when the log is written.  It
     is in ISO 8601 format.
 
-  <master-pid>
-    It is a master process ID.
+  <main-pid>
+    It is a main process ID.
 
   <current-pid>
     It is a process ID which writes this log.
@@ -1654,30 +1867,30 @@ SIGUSR2
 
   Fork and execute nghttpx.  It will execute the binary in the same
   path with same command-line arguments and environment variables.  As
-  of nghttpx version 1.20.0, the new master process sends SIGQUIT to
-  the original master process when it is ready to serve requests.  For
-  the earlier versions of nghttpx, user has to send SIGQUIT to the
-  original master process.
+  of nghttpx version 1.20.0, the new main process sends SIGQUIT to the
+  original main process when it is ready to serve requests.  For the
+  earlier versions of nghttpx, user has to send SIGQUIT to the
+  original main process.
 
   The difference between SIGUSR2 (+ SIGQUIT) and SIGHUP is that former
-  is usually used to execute new binary, and the master process is
-  newly spawned.  On the other hand, the latter just reloads
-  configuration file, and the same master process continues to exist.
+  is usually used to execute new binary, and the main process is newly
+  spawned.  On the other hand, the latter just reloads configuration
+  file, and the same main process continues to exist.
 
 .. note::
 
   nghttpx consists of multiple processes: one process for processing
   these signals, and another one for processing requests.  The former
-  spawns the latter.  The former is called master process, and the
+  spawns the latter.  The former is called main process, and the
   latter is called worker process.  If neverbleed is enabled, the
   worker process spawns neverbleed daemon process which does RSA key
-  processing.  The above signal must be sent to the master process.
-  If the other processes received one of them, it is ignored.  This
+  processing.  The above signal must be sent to the main process.  If
+  the other processes received one of them, it is ignored.  This
   behaviour of these processes may change in the future release.  In
-  other words, in the future release, the processes other than master
+  other words, in the future release, the processes other than main
   process may terminate upon the reception of these signals.
   Therefore these signals should not be sent to the processes other
-  than master process.
+  than main process.
 
 SERVER PUSH
 -----------
index 44edcbf..dcde6cb 100644 (file)
@@ -6,7 +6,7 @@ Architecture
 
 The most notable point in nghttp2 library architecture is it does not
 perform any I/O.  nghttp2 only performs HTTP/2 protocol stuff based on
-input byte strings.  It will calls callback functions set by
+input byte strings.  It will call callback functions set by
 applications while processing input.  The output of nghttp2 is just
 byte string.  An application is responsible to send these output to
 the remote peer.  The callback functions may be called while producing
index b2aa9d0..a5330ec 100644 (file)
@@ -26,16 +26,16 @@ Coding style
 We use clang-format to format source code consistently.  The
 clang-format configuration file .clang-format is located at the root
 directory.  Since clang-format produces slightly different results
-between versions, we currently use clang-format-9.
+between versions, we currently use clang-format-12.
 
 To detect any violation to the coding style, we recommend to setup git
 pre-commit hook to check coding style of the changes you introduced.
 The pre-commit file is located at the root directory.  Copy it under
 .git/hooks and make sure that it is executable.  The pre-commit script
 uses clang-format-diff.py to detect any style errors.  If it is not in
-your PATH or it exists under different name (e.g., clang-format-diff-9
-in debian), either add it to PATH variable or add git option
-``clangformatdiff.binary`` to point to the script.
+your PATH or it exists under different name (e.g.,
+clang-format-diff-12 in debian), either add it to PATH variable or add
+git option ``clangformatdiff.binary`` to point to the script.
 
 For emacs users, integrating clang-format to emacs is very easy.
 clang-format.el should come with clang distribution.  If it is not
index 133f900..2ee2754 100644 (file)
@@ -131,3 +131,12 @@ specify ``unix:`` followed by the path to UNIX domain socket.  For
 example, if UNIX domain socket is ``/tmp/nghttpx.sock``, use
 ``--base-uri=unix:/tmp/nghttpx.sock``.  h2load uses scheme, host and
 port in the first URI in command-line or input file.
+
+HTTP/3
+------
+
+h2load supports HTTP/3 if it is built with HTTP/3 enabled.  HTTP/3
+support is experimental.
+
+In order to send HTTP/3 request, specify ``h3`` to
+:option:`--npn-list`.
index c8f688d..db6e7b8 100644 (file)
@@ -1,4 +1,4 @@
-.. nghttp2 documentation master file, created by
+.. nghttp2 documentation main file, created by
    sphinx-quickstart on Sun Mar 11 22:57:49 2012.
    You can adapt this file completely to your liking, but it should at least
    contain the root `toctree` directive.
@@ -18,6 +18,7 @@ Contents:
 
    package_README
    contribute
+   security
    building-android-binary
    tutorial-client
    tutorial-server
index bbb7c20..48faddd 100644 (file)
@@ -14,8 +14,8 @@ Default mode
 
 If nghttpx is invoked without :option:`--http2-proxy`, it operates in
 default mode.  In this mode, it works as reverse proxy (gateway) for
-both HTTP/2 and HTTP/1 clients to backend servers.  This is also known
-as "HTTP/2 router".
+HTTP/3, HTTP/2 and HTTP/1 clients to backend servers.  This is also
+known as "HTTP/2 router".
 
 By default, frontend connection is encrypted using SSL/TLS.  So
 server's private key and certificate must be supplied to the command
@@ -28,6 +28,9 @@ the frontend, and an HTTP/1 connection can be upgraded to HTTP/2 using
 HTTP Upgrade.  Starting HTTP/2 connection by sending HTTP/2 connection
 preface is also supported.
 
+In order to receive HTTP/3 traffic, use ``quic`` parameter in
+:option:`--frontend` option (.e.g, ``--frontend='*,443;quic'``)
+
 nghttpx can listen on multiple frontend addresses.  This is achieved
 by using multiple :option:`--frontend` options.  For each frontend
 address, TLS can be enabled or disabled.
@@ -228,7 +231,7 @@ process.  It will do fork and execute new executable, using same
 command-line arguments and environment variables.
 
 As of nghttpx version 1.20.0, that is all you have to do.  The new
-master process sends QUIT signal to the original process, when it is
+main process sends QUIT signal to the original process, when it is
 ready to serve requests, to shut it down gracefully.
 
 For earlier versions of nghttpx, you have to do one more thing.  At
@@ -239,7 +242,7 @@ current process will exit.  At this point, only new nghttpx process
 exists and serves incoming requests.
 
 If you want to just reload configuration file without executing new
-binary, send SIGHUP to nghttpx master process.
+binary, send SIGHUP to nghttpx main process.
 
 Re-opening log files
 --------------------
@@ -445,10 +448,10 @@ nghttpx server accepts any of the identity and secret pairs in the
 file.  The default cipher suite list does not contain PSK cipher
 suites.  In order to use PSK, PSK cipher suite must be enabled by
 using :option:`--ciphers` option.  The desired PSK cipher suite may be
-listed in `HTTP/2 cipher black list
+listed in `HTTP/2 cipher block list
 <https://tools.ietf.org/html/rfc7540#appendix-A>`_.  In order to use
-such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by
-using :option:`--no-http2-cipher-black-list` option.  But you should
+such PSK cipher suite with HTTP/2, disable HTTP/2 cipher block list by
+using :option:`--no-http2-cipher-block-list` option.  But you should
 understand its implications.
 
 At the time of writing, even if only PSK cipher suites are specified
@@ -468,10 +471,10 @@ used, like so:
 The default cipher suite list does not contain PSK cipher suites.  In
 order to use PSK, PSK cipher suite must be enabled by using
 :option:`--client-ciphers` option.  The desired PSK cipher suite may
-be listed in `HTTP/2 cipher black list
+be listed in `HTTP/2 cipher block list
 <https://tools.ietf.org/html/rfc7540#appendix-A>`_.  In order to use
-such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by
-using :option:`--client-no-http2-cipher-black-list` option.  But you
+such PSK cipher suite with HTTP/2, disable HTTP/2 cipher block list by
+using :option:`--client-no-http2-cipher-block-list` option.  But you
 should understand its implications.
 
 TLSv1.3
@@ -509,6 +512,60 @@ Bootstrapping WebSockets with HTTP/2 for both frontend and backend
 connections.  This feature is enabled by default and no configuration
 is required.
 
+WebSockets over HTTP/3 is also supported.
+
+HTTP/3
+------
+
+nghttpx supports HTTP/3 if it is built with HTTP/3 support enabled.
+HTTP/3 support is experimental.
+
+In order to listen UDP port to receive HTTP/3 traffic,
+:option:`--frontend` option must have ``quic`` parameter:
+
+.. code-block:: text
+
+   frontend=*,443;quic
+
+The above example makes nghttpx receive HTTP/3 traffic on UDP
+port 443.
+
+nghttpx does not support HTTP/3 on backend connection.
+
+Hot swapping (SIGUSR2) or configuration reload (SIGHUP) require eBPF
+program.  Without eBPF, old worker processes keep getting HTTP/3
+traffic and do not work as intended.  The QUIC keying material to
+encrypt Connection ID must be set with
+:option:`--frontend-quic-secret-file` and must provide the existing
+keys in order to keep the existing connections alive during reload.
+
+The construction of Connection ID closely follows Block Cipher CID
+Algorithm described in `QUIC-LB draft
+<https://datatracker.ietf.org/doc/html/draft-ietf-quic-load-balancers>`_.
+A Connection ID that nghttpx generates is always 20 bytes long.  It
+uses first 2 bits as a configuration ID.  The remaining bits in the
+first byte are reserved and random.  The next 4 bytes are server ID.
+The next 4 bytes are used to route UDP datagram to a correct
+``SO_REUSEPORT`` socket.  The remaining bytes are randomly generated.
+The server ID and the next 12 bytes are encrypted with AES-ECB.  The
+key is derived from the keying materials stored in a file specified by
+:option:`--frontend-quic-secret-file`.  The first 2 bits of keying
+material in the file is used as a configuration ID.  The remaining
+bits and following 3 bytes are reserved and unused.  The next 32 bytes
+are used as an initial secret.  The remaining 32 bytes are used as a
+salt.  The encryption key is generated by `HKDF
+<https://datatracker.ietf.org/doc/html/rfc5869>`_ with SHA256 and
+these keying materials and ``connection id encryption key`` as info.
+
+In order announce that HTTP/3 endpoint is available, you should
+specify alt-svc header field.  For example, the following options send
+alt-svc header field in HTTP/1.1 and HTTP/2 response:
+
+.. code-block:: text
+
+   altsvc=h3,443,,,ma=3600
+   http2-altsvc=h3,443,,,ma=3600
+
 Migration from nghttpx v1.18.x or earlier
 -----------------------------------------
 
@@ -516,10 +573,10 @@ As of nghttpx v1.19.0, :option:`--ciphers` option only changes cipher
 list for frontend TLS connection.  In order to change cipher list for
 backend connection, use :option:`--client-ciphers` option.
 
-Similarly, :option:`--no-http2-cipher-black-list` option only disables
-HTTP/2 cipher black list for frontend connection.  In order to disable
-HTTP/2 cipher black list for backend connection, use
-:option:`--client-no-http2-cipher-black-list` option.
+Similarly, :option:`--no-http2-cipher-block-list` option only disables
+HTTP/2 cipher block list for frontend connection.  In order to disable
+HTTP/2 cipher block list for backend connection, use
+:option:`--client-no-http2-cipher-block-list` option.
 
 ``--accept-proxy-protocol`` option was deprecated.  Instead, use
 ``proxyproto`` parameter in :option:`--frontend` option to enable
index d64b43c..92fab33 100644 (file)
@@ -13,7 +13,7 @@ The extension module is called ``nghttp2``.
 determined by configure script.  If the detected Python version is not
 what you expect, specify a path to Python executable in ``PYTHON``
 variable as an argument to configure script (e.g., ``./configure
-PYTHON=/usr/bin/python3.5``).
+PYTHON=/usr/bin/python3.8``).
 
 HPACK API
 ---------
@@ -137,14 +137,14 @@ HTTP/2 servers
 .. note::
 
    We use :py:mod:`asyncio` for HTTP/2 server classes, and ALPN.
-   Therefore, Python 3.5 or later is required to use these objects.
-   To explicitly configure nghttp2 build to use Python 3.5, specify
-   the ``PYTHON`` variable to the path to Python 3.5 executable when
+   Therefore, Python 3.8 or later is required to use these objects.
+   To explicitly configure nghttp2 build to use Python 3.8, specify
+   the ``PYTHON`` variable to the path to Python 3.8 executable when
    invoking configure script like this:
 
    .. code-block:: text
 
-       $ ./configure PYTHON=/usr/bin/python3.5
+       $ ./configure PYTHON=/usr/bin/python3.8
 
 .. py:class:: HTTP2Server(address, RequestHandlerClass, ssl=None)
 
@@ -336,7 +336,7 @@ The following example illustrates :py:class:`HTTP2Server` and
 
 .. code-block:: python
 
-    #!/usr/bin/env python
+    #!/usr/bin/env python3
 
     import io, ssl
 
@@ -367,7 +367,7 @@ response body generation.  This is simplified reverse proxy:
 
 .. code-block:: python
 
-    #!/usr/bin/env python
+    #!/usr/bin/env python3
 
     import ssl
     import os
diff --git a/doc/sources/security.rst b/doc/sources/security.rst
new file mode 100644 (file)
index 0000000..ab27eab
--- /dev/null
@@ -0,0 +1,38 @@
+Security Process
+================
+
+If you find a vulnerability in our software, please send the email to
+"tatsuhiro.t at gmail dot com" about its details instead of submitting
+issues on github issue page.  It is a standard practice not to
+disclose vulnerability information publicly until a fixed version is
+released, or mitigation is worked out.  In the future, we may setup a
+dedicated mail address for this purpose.
+
+If we identify that the reported issue is really a vulnerability, we
+open a new security advisory draft using `GitHub security feature
+<https://github.com/nghttp2/nghttp2/security>`_ and discuss the
+mitigation and bug fixes there.  The fixes are committed to the
+private repository.
+
+We write the security advisory and get CVE number from GitHub
+privately.  We also discuss the disclosure date to the public.
+
+We make a new release with the fix at the same time when the
+vulnerability is disclosed to public.
+
+At least 7 days before the public disclosure date, we will post
+security advisory (which includes all the details of the vulnerability
+and the possible mitigation strategies) and the patches to fix the
+issue to `distros@openwall
+<https://oss-security.openwall.org/wiki/mailing-lists/distros>`_
+mailing list.  We also open a new issue on `nghttp2 issue tracker
+<https://github.com/nghttp2/nghttp2/issues>`_ which notifies that the
+upcoming release will have a security fix.  The ``SECURITY`` label is
+attached to this kind of issue.
+
+Before few hours of new release, we merge the fixes to the master
+branch (and/or a release branch if necessary) and make a new release.
+Security advisory is disclosed on GitHub.  We also post the
+vulnerability information to `oss-security
+<https://oss-security.openwall.org/wiki/mailing-lists/oss-security>`_
+mailing list.
index 801ac18..f358d1a 100644 (file)
@@ -64,9 +64,9 @@ Types (structs, unions and typedefs)
         :type:`nghttp2_on_frame_send_callback`, and
         :type:`nghttp2_on_frame_not_send_callback`), it may not be
         NULL-terminated if header field is passed from application with
-        the flag :macro:`NGHTTP2_NV_FLAG_NO_COPY_NAME`).  When application
-        is constructing this struct, *name* is not required to be
-        NULL-terminated.
+        the flag :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`).
+        When application is constructing this struct, *name* is not
+        required to be NULL-terminated.
     .. member::   uint8_t *value
 
         The *value* byte string.  If this struct is presented from
@@ -76,9 +76,9 @@ Types (structs, unions and typedefs)
         :type:`nghttp2_on_frame_send_callback`, and
         :type:`nghttp2_on_frame_not_send_callback`), it may not be
         NULL-terminated if header field is passed from application with
-        the flag :macro:`NGHTTP2_NV_FLAG_NO_COPY_VALUE`).  When
-        application is constructing this struct, *value* is not required
-        to be NULL-terminated.
+        the flag :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE`).
+        When application is constructing this struct, *value* is not
+        required to be NULL-terminated.
     .. member::   size_t namelen
 
         The length of the *name*, excluding terminating NULL.
@@ -123,7 +123,7 @@ Types (structs, unions and typedefs)
 
         The pointer to an arbitrary object.
 
-.. type:: typedef ssize_t (*nghttp2_data_source_read_callback)( nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, uint32_t *data_flags, nghttp2_data_source *source, void *user_data)
+.. type:: ssize_t (*nghttp2_data_source_read_callback)( nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, uint32_t *data_flags, nghttp2_data_source *source, void *user_data)
 
     
     Callback function invoked when the library wants to read data from
@@ -131,38 +131,41 @@ Types (structs, unions and typedefs)
     The implementation of this function must read at most *length*
     bytes of data from *source* (or possibly other places) and store
     them in *buf* and return number of data stored in *buf*.  If EOF is
-    reached, set :macro:`NGHTTP2_DATA_FLAG_EOF` flag in *\*data_flags*.
+    reached, set :macro:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag
+    in *\*data_flags*.
     
     Sometime it is desirable to avoid copying data into *buf* and let
     application to send data directly.  To achieve this, set
-    :macro:`NGHTTP2_DATA_FLAG_NO_COPY` to *\*data_flags* (and possibly
-    other flags, just like when we do copy), and return the number of
-    bytes to send without copying data into *buf*.  The library, seeing
-    :macro:`NGHTTP2_DATA_FLAG_NO_COPY`, will invoke
+    :macro:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` to
+    *\*data_flags* (and possibly other flags, just like when we do
+    copy), and return the number of bytes to send without copying data
+    into *buf*.  The library, seeing
+    :macro:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY`, will invoke
     :type:`nghttp2_send_data_callback`.  The application must send
     complete DATA frame in that callback.
     
     If this callback is set by `nghttp2_submit_request()`,
     `nghttp2_submit_response()` or `nghttp2_submit_headers()` and
     `nghttp2_submit_data()` with flag parameter
-    :macro:`NGHTTP2_FLAG_END_STREAM` set, and
-    :macro:`NGHTTP2_DATA_FLAG_EOF` flag is set to *\*data_flags*, DATA
-    frame will have END_STREAM flag set.  Usually, this is expected
-    behaviour and all are fine.  One exception is send trailer fields.
-    You cannot send trailer fields after sending frame with END_STREAM
-    set.  To avoid this problem, one can set
-    :macro:`NGHTTP2_DATA_FLAG_NO_END_STREAM` along with
-    :macro:`NGHTTP2_DATA_FLAG_EOF` to signal the library not to set
-    END_STREAM in DATA frame.  Then application can use
-    `nghttp2_submit_trailer()` to send trailer fields.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` set, and
+    :macro:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag is set to
+    *\*data_flags*, DATA frame will have END_STREAM flag set.  Usually,
+    this is expected behaviour and all are fine.  One exception is send
+    trailer fields.  You cannot send trailer fields after sending frame
+    with END_STREAM set.  To avoid this problem, one can set
+    :macro:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM` along
+    with :macro:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` to signal the
+    library not to set END_STREAM in DATA frame.  Then application can
+    use `nghttp2_submit_trailer()` to send trailer fields.
     `nghttp2_submit_trailer()` can be called inside this callback.
     
     If the application wants to postpone DATA frames (e.g.,
     asynchronous I/O, or reading data blocks for long time), it is
-    achieved by returning :macro:`NGHTTP2_ERR_DEFERRED` without reading
-    any data in this invocation.  The library removes DATA frame from
-    the outgoing queue temporarily.  To move back deferred DATA frame
-    to outgoing queue, call `nghttp2_session_resume_data()`.
+    achieved by returning :macro:`nghttp2_error.NGHTTP2_ERR_DEFERRED`
+    without reading any data in this invocation.  The library removes
+    DATA frame from the outgoing queue temporarily.  To move back
+    deferred DATA frame to outgoing queue, call
+    `nghttp2_session_resume_data()`.
     
     By default, *length* is limited to 16KiB at maximum.  If peer
     allows larger frames, application can enlarge transmission buffer
@@ -171,16 +174,17 @@ Types (structs, unions and typedefs)
     
     If the application just wants to return from
     `nghttp2_session_send()` or `nghttp2_session_mem_send()` without
-    sending anything, return :macro:`NGHTTP2_ERR_PAUSE`.
+    sending anything, return :macro:`nghttp2_error.NGHTTP2_ERR_PAUSE`.
     
     In case of error, there are 2 choices. Returning
-    :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close the stream
-    by issuing RST_STREAM with :macro:`NGHTTP2_INTERNAL_ERROR`.  If a
-    different error code is desirable, use
-    `nghttp2_submit_rst_stream()` with a desired error code and then
-    return :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  Returning
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the entire session
-    failure.
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+    close the stream by issuing RST_STREAM with
+    :macro:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`.  If a different
+    error code is desirable, use `nghttp2_submit_rst_stream()` with a
+    desired error code and then return
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+    Returning :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will
+    signal the entire session failure.
 .. type:: nghttp2_data_provider
 
     
@@ -433,7 +437,7 @@ Types (structs, unions and typedefs)
 
         The extension frame.
 
-.. type:: typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session, const uint8_t *data, size_t length, int flags, void *user_data)
+.. type:: ssize_t (*nghttp2_send_callback)(nghttp2_session *session, const uint8_t *data, size_t length, int flags, void *user_data)
 
     
     Callback function invoked when *session* wants to send data to the
@@ -441,8 +445,9 @@ Types (structs, unions and typedefs)
     *length* bytes of data stored in *data*.  The *flags* is currently
     not used and always 0. It must return the number of bytes sent if
     it succeeds.  If it cannot send any single byte without blocking,
-    it must return :macro:`NGHTTP2_ERR_WOULDBLOCK`.  For other errors,
-    it must return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  The
+    it must return :macro:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`.  For
+    other errors, it must return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  The
     *user_data* pointer is the third argument passed in to the call to
     `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
     
@@ -462,12 +467,13 @@ Types (structs, unions and typedefs)
       and it is very inefficient.  An application should be responsible
       to buffer up small chunks of data as necessary to avoid this
       situation.
-.. type:: typedef int (*nghttp2_send_data_callback)(nghttp2_session *session, nghttp2_frame *frame, const uint8_t *framehd, size_t length, nghttp2_data_source *source, void *user_data)
+.. type:: int (*nghttp2_send_data_callback)(nghttp2_session *session, nghttp2_frame *frame, const uint8_t *framehd, size_t length, nghttp2_data_source *source, void *user_data)
 
     
-    Callback function invoked when :macro:`NGHTTP2_DATA_FLAG_NO_COPY` is
-    used in :type:`nghttp2_data_source_read_callback` to send complete
-    DATA frame.
+    Callback function invoked when
+    :macro:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in
+    :type:`nghttp2_data_source_read_callback` to send complete DATA
+    frame.
     
     The *frame* is a DATA frame to send.  The *framehd* is the
     serialized frame header (9 bytes). The *length* is the length of
@@ -485,22 +491,23 @@ Types (structs, unions and typedefs)
     If all data were written successfully, return 0.
     
     If it cannot send any data at all, just return
-    :macro:`NGHTTP2_ERR_WOULDBLOCK`; the library will call this callback
-    with the same parameters later (It is recommended to send complete
-    DATA frame at once in this function to deal with error; if partial
-    frame data has already sent, it is impossible to send another data
-    in that state, and all we can do is tear down connection).  When
-    data is fully processed, but application wants to make
-    `nghttp2_session_mem_send()` or `nghttp2_session_send()` return
-    immediately without processing next frames, return
-    :macro:`NGHTTP2_ERR_PAUSE`.  If application decided to reset this
-    stream, return :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then
+    :macro:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`; the library will call
+    this callback with the same parameters later (It is recommended to
+    send complete DATA frame at once in this function to deal with
+    error; if partial frame data has already sent, it is impossible to
+    send another data in that state, and all we can do is tear down
+    connection).  When data is fully processed, but application wants
+    to make `nghttp2_session_mem_send()` or `nghttp2_session_send()`
+    return immediately without processing next frames, return
+    :macro:`nghttp2_error.NGHTTP2_ERR_PAUSE`.  If application decided to
+    reset this stream, return
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then
     the library will send RST_STREAM with INTERNAL_ERROR as error code.
     The application can also return
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`, which will result in
-    connection closure.  Returning any other value is treated as
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
-.. type:: typedef ssize_t (*nghttp2_recv_callback)(nghttp2_session *session, uint8_t *buf, size_t length, int flags, void *user_data)
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which will
+    result in connection closure.  Returning any other value is treated
+    as :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
+.. type:: ssize_t (*nghttp2_recv_callback)(nghttp2_session *session, uint8_t *buf, size_t length, int flags, void *user_data)
 
     
     Callback function invoked when *session* wants to receive data from
@@ -509,11 +516,13 @@ Types (structs, unions and typedefs)
     currently not used and always 0.  It must return the number of
     bytes written in *buf* if it succeeds.  If it cannot read any
     single byte without blocking, it must return
-    :macro:`NGHTTP2_ERR_WOULDBLOCK`.  If it gets EOF before it reads any
-    single byte, it must return :macro:`NGHTTP2_ERR_EOF`.  For other
-    errors, it must return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
-    Returning 0 is treated as :macro:`NGHTTP2_ERR_WOULDBLOCK`.  The
-    *user_data* pointer is the third argument passed in to the call to
+    :macro:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`.  If it gets EOF
+    before it reads any single byte, it must return
+    :macro:`nghttp2_error.NGHTTP2_ERR_EOF`.  For other errors, it must
+    return :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+    Returning 0 is treated as
+    :macro:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`.  The *user_data*
+    pointer is the third argument passed in to the call to
     `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
     
     This callback is required if the application uses
@@ -523,7 +532,7 @@ Types (structs, unions and typedefs)
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_recv_callback()`.
-.. type:: typedef int (*nghttp2_on_frame_recv_callback)(nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
+.. type:: int (*nghttp2_on_frame_recv_callback)(nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
 
     
     Callback function invoked by `nghttp2_session_recv()` and
@@ -552,11 +561,12 @@ Types (structs, unions and typedefs)
     The implementation of this function must return 0 if it succeeds.
     If nonzero value is returned, it is treated as fatal error and
     `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_on_frame_recv_callback()`.
-.. type:: typedef int (*nghttp2_on_invalid_frame_recv_callback)( nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, void *user_data)
+.. type:: int (*nghttp2_on_invalid_frame_recv_callback)( nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, void *user_data)
 
     
     Callback function invoked by `nghttp2_session_recv()` and
@@ -575,11 +585,12 @@ Types (structs, unions and typedefs)
     The implementation of this function must return 0 if it succeeds.
     If nonzero is returned, it is treated as fatal error and
     `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_on_invalid_frame_recv_callback()`.
-.. type:: typedef int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session, uint8_t flags, int32_t stream_id, const uint8_t *data, size_t len, void *user_data)
+.. type:: int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session, uint8_t flags, int32_t stream_id, const uint8_t *data, size_t len, void *user_data)
 
     
     Callback function invoked when a chunk of data in DATA frame is
@@ -593,9 +604,9 @@ Types (structs, unions and typedefs)
     `nghttp2_session_server_new()`.
     
     If the application uses `nghttp2_session_mem_recv()`, it can return
-    :macro:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
-    return without processing further input bytes.  The memory by
-    pointed by the *data* is retained until
+    :macro:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
+    `nghttp2_session_mem_recv()` return without processing further
+    input bytes.  The memory by pointed by the *data* is retained until
     `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
     The application must retain the input bytes which was used to
     produce the *data* parameter, because it may refer to the memory
@@ -604,11 +615,12 @@ Types (structs, unions and typedefs)
     The implementation of this function must return 0 if it succeeds.
     If nonzero is returned, it is treated as fatal error, and
     `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_on_data_chunk_recv_callback()`.
-.. type:: typedef int (*nghttp2_before_frame_send_callback)(nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
+.. type:: int (*nghttp2_before_frame_send_callback)(nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
 
     
     Callback function invoked just before the non-DATA frame *frame* is
@@ -617,23 +629,24 @@ Types (structs, unions and typedefs)
     `nghttp2_session_server_new()`.
     
     The implementation of this function must return 0 if it succeeds.
-    It can also return :macro:`NGHTTP2_ERR_CANCEL` to cancel the
-    transmission of the given frame.
+    It can also return :macro:`nghttp2_error.NGHTTP2_ERR_CANCEL` to
+    cancel the transmission of the given frame.
     
     If there is a fatal error while executing this callback, the
-    implementation should return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`,
-    which makes `nghttp2_session_send()` and
-    `nghttp2_session_mem_send()` functions immediately return
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    implementation should return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which makes
+    `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     If the other value is returned, it is treated as if
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned.  But the
-    implementation should not rely on this since the library may define
-    new return value to extend its capability.
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
+    But the implementation should not rely on this since the library
+    may define new return value to extend its capability.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_before_frame_send_callback()`.
-.. type:: typedef int (*nghttp2_on_frame_send_callback)(nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
+.. type:: int (*nghttp2_on_frame_send_callback)(nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
 
     
     Callback function invoked after the frame *frame* is sent.  The
@@ -643,11 +656,12 @@ Types (structs, unions and typedefs)
     The implementation of this function must return 0 if it succeeds.
     If nonzero is returned, it is treated as fatal error and
     `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_on_frame_send_callback()`.
-.. type:: typedef int (*nghttp2_on_frame_not_send_callback)(nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, void *user_data)
+.. type:: int (*nghttp2_on_frame_not_send_callback)(nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, void *user_data)
 
     
     Callback function invoked after the non-DATA frame *frame* is not
@@ -660,14 +674,15 @@ Types (structs, unions and typedefs)
     The implementation of this function must return 0 if it succeeds.
     If nonzero is returned, it is treated as fatal error and
     `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     `nghttp2_session_get_stream_user_data()` can be used to get
     associated data.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_on_frame_not_send_callback()`.
-.. type:: typedef int (*nghttp2_on_stream_close_callback)(nghttp2_session *session, int32_t stream_id, uint32_t error_code, void *user_data)
+.. type:: int (*nghttp2_on_stream_close_callback)(nghttp2_session *session, int32_t stream_id, uint32_t error_code, void *user_data)
 
     
     Callback function invoked when the stream *stream_id* is closed.
@@ -685,11 +700,12 @@ Types (structs, unions and typedefs)
     If nonzero is returned, it is treated as fatal error and
     `nghttp2_session_recv()`, `nghttp2_session_mem_recv()`,
     `nghttp2_session_send()`, and `nghttp2_session_mem_send()`
-    functions immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    functions immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_on_stream_close_callback()`.
-.. type:: typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
+.. type:: int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
 
     
     Callback function invoked when the reception of header block in
@@ -697,10 +713,11 @@ Types (structs, unions and typedefs)
     will be emitted by :type:`nghttp2_on_header_callback`.
     
     The ``frame->hd.flags`` may not have
-    :macro:`NGHTTP2_FLAG_END_HEADERS` flag set, which indicates that one
-    or more CONTINUATION frames are involved.  But the application does
-    not need to care about that because the header name/value pairs are
-    emitted transparently regardless of CONTINUATION frames.
+    :macro:`nghttp2_flag.NGHTTP2_FLAG_END_HEADERS` flag set, which
+    indicates that one or more CONTINUATION frames are involved.  But
+    the application does not need to care about that because the header
+    name/value pairs are emitted transparently regardless of
+    CONTINUATION frames.
     
     The server applications probably create an object to store
     information about new stream if ``frame->hd.type ==
@@ -723,30 +740,35 @@ Types (structs, unions and typedefs)
     trailer fields also has ``frame->headers.cat ==
     NGHTTP2_HCAT_HEADERS`` which does not contain any status code.
     
-    Returning :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close
-    the stream (promised stream if frame is PUSH_PROMISE) by issuing
-    RST_STREAM with :macro:`NGHTTP2_INTERNAL_ERROR`.  In this case,
+    Returning
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+    close the stream (promised stream if frame is PUSH_PROMISE) by
+    issuing RST_STREAM with
+    :macro:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`.  In this case,
     :type:`nghttp2_on_header_callback` and
     :type:`nghttp2_on_frame_recv_callback` will not be invoked.  If a
     different error code is desirable, use
     `nghttp2_submit_rst_stream()` with a desired error code and then
-    return :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  Again, use
-    ``frame->push_promise.promised_stream_id`` as stream_id parameter
-    in `nghttp2_submit_rst_stream()` if frame is PUSH_PROMISE.
+    return :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+    Again, use ``frame->push_promise.promised_stream_id`` as stream_id
+    parameter in `nghttp2_submit_rst_stream()` if frame is
+    PUSH_PROMISE.
     
     The implementation of this function must return 0 if it succeeds.
-    It can return :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` to
+    It can return
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` to
     reset the stream (promised stream if frame is PUSH_PROMISE).  For
     critical errors, it must return
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other value is
-    returned, it is treated as if :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`
-    is returned.  If :macro:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+    value is returned, it is treated as if
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned.  If
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
     `nghttp2_session_mem_recv()` function will immediately return
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_on_begin_headers_callback()`.
-.. type:: typedef int (*nghttp2_on_header_callback)(nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, void *user_data)
+.. type:: int (*nghttp2_on_header_callback)(nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, void *user_data)
 
     
     Callback function invoked when a header name/value pair is received
@@ -754,16 +776,17 @@ Types (structs, unions and typedefs)
     The *value* of length *valuelen* is header value.  The *flags* is
     bitwise OR of one or more of :type:`nghttp2_nv_flag`.
     
-    If :macro:`NGHTTP2_NV_FLAG_NO_INDEX` is set in *flags*, the receiver
-    must not index this name/value pair when forwarding it to the next
-    hop.  More specifically, "Literal Header Field never Indexed"
-    representation must be used in HPACK encoding.
+    If :macro:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_INDEX` is set in
+    *flags*, the receiver must not index this name/value pair when
+    forwarding it to the next hop.  More specifically, "Literal Header
+    Field never Indexed" representation must be used in HPACK encoding.
     
     When this callback is invoked, ``frame->hd.type`` is either
-    :macro:`NGHTTP2_HEADERS` or :macro:`NGHTTP2_PUSH_PROMISE`.  After all
-    header name/value pairs are processed with this callback, and no
-    error has been detected, :type:`nghttp2_on_frame_recv_callback`
-    will be invoked.  If there is an error in decompression,
+    :macro:`nghttp2_frame_type.NGHTTP2_HEADERS` or
+    :macro:`nghttp2_frame_type.NGHTTP2_PUSH_PROMISE`.  After all header
+    name/value pairs are processed with this callback, and no error has
+    been detected, :type:`nghttp2_on_frame_recv_callback` will be
+    invoked.  If there is an error in decompression,
     :type:`nghttp2_on_frame_recv_callback` for the *frame* will not be
     invoked.
     
@@ -781,34 +804,39 @@ Types (structs, unions and typedefs)
     explained in :ref:`http-messaging` section.
     
     If the application uses `nghttp2_session_mem_recv()`, it can return
-    :macro:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
-    return without processing further input bytes.  The memory pointed
-    by *frame*, *name* and *value* parameters are retained until
-    `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
-    The application must retain the input bytes which was used to
-    produce these parameters, because it may refer to the memory region
-    included in the input bytes.
-    
-    Returning :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close
-    the stream (promised stream if frame is PUSH_PROMISE) by issuing
-    RST_STREAM with :macro:`NGHTTP2_INTERNAL_ERROR`.  In this case,
+    :macro:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
+    `nghttp2_session_mem_recv()` return without processing further
+    input bytes.  The memory pointed by *frame*, *name* and *value*
+    parameters are retained until `nghttp2_session_mem_recv()` or
+    `nghttp2_session_recv()` is called.  The application must retain
+    the input bytes which was used to produce these parameters, because
+    it may refer to the memory region included in the input bytes.
+    
+    Returning
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+    close the stream (promised stream if frame is PUSH_PROMISE) by
+    issuing RST_STREAM with
+    :macro:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`.  In this case,
     :type:`nghttp2_on_header_callback` and
     :type:`nghttp2_on_frame_recv_callback` will not be invoked.  If a
     different error code is desirable, use
     `nghttp2_submit_rst_stream()` with a desired error code and then
-    return :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  Again, use
-    ``frame->push_promise.promised_stream_id`` as stream_id parameter
-    in `nghttp2_submit_rst_stream()` if frame is PUSH_PROMISE.
+    return :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+    Again, use ``frame->push_promise.promised_stream_id`` as stream_id
+    parameter in `nghttp2_submit_rst_stream()` if frame is
+    PUSH_PROMISE.
     
     The implementation of this function must return 0 if it succeeds.
-    It may return :macro:`NGHTTP2_ERR_PAUSE` or
-    :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  For other critical
-    failures, it must return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If
-    the other nonzero value is returned, it is treated as
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
+    It may return :macro:`nghttp2_error.NGHTTP2_ERR_PAUSE` or
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  For
+    other critical failures, it must return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+    nonzero value is returned, it is treated as
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
     `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_on_header_callback()`.
@@ -820,7 +848,7 @@ Types (structs, unions and typedefs)
       of header fields or large header fields to cause out of memory in
       local endpoint.  Due to how HPACK works, peer can do this
       effectively without using much memory on their own.
-.. type:: typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name, nghttp2_rcbuf *value, uint8_t flags, void *user_data)
+.. type:: int (*nghttp2_on_header_callback2)(nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name, nghttp2_rcbuf *value, uint8_t flags, void *user_data)
 
     
     Callback function invoked when a header name/value pair is received
@@ -839,7 +867,7 @@ Types (structs, unions and typedefs)
     the function to free memory is the one belongs to the mem
     parameter.  As long as this free function alives, *name* and
     *value* can live after *session* was destroyed.
-.. type:: typedef int (*nghttp2_on_invalid_header_callback)( nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, void *user_data)
+.. type:: int (*nghttp2_on_invalid_header_callback)( nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, void *user_data)
 
     
     Callback function invoked when a invalid header name/value pair is
@@ -861,15 +889,16 @@ Types (structs, unions and typedefs)
     
     With this callback, application inspects the incoming invalid
     field, and it also can reset stream from this callback by returning
-    :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  By default, the
-    error code is :macro:`NGHTTP2_PROTOCOL_ERROR`.  To change the error
-    code, call `nghttp2_submit_rst_stream()` with the error code of
-    choice in addition to returning
-    :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  By
+    default, the error code is
+    :macro:`nghttp2_error_code.NGHTTP2_PROTOCOL_ERROR`.  To change the
+    error code, call `nghttp2_submit_rst_stream()` with the error code
+    of choice in addition to returning
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
     
     If 0 is returned, the header field is ignored, and the stream is
     not reset.
-.. type:: typedef int (*nghttp2_on_invalid_header_callback2)( nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name, nghttp2_rcbuf *value, uint8_t flags, void *user_data)
+.. type:: int (*nghttp2_on_invalid_header_callback2)( nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name, nghttp2_rcbuf *value, uint8_t flags, void *user_data)
 
     
     Callback function invoked when a invalid header name/value pair is
@@ -890,12 +919,13 @@ Types (structs, unions and typedefs)
     
     With this callback, application inspects the incoming invalid
     field, and it also can reset stream from this callback by returning
-    :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  By default, the
-    error code is :macro:`NGHTTP2_INTERNAL_ERROR`.  To change the error
-    code, call `nghttp2_submit_rst_stream()` with the error code of
-    choice in addition to returning
-    :macro:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
-.. type:: typedef ssize_t (*nghttp2_select_padding_callback)(nghttp2_session *session, const nghttp2_frame *frame, size_t max_payloadlen, void *user_data)
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  By
+    default, the error code is
+    :macro:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`.  To change the
+    error code, call `nghttp2_submit_rst_stream()` with the error code
+    of choice in addition to returning
+    :macro:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+.. type:: ssize_t (*nghttp2_select_padding_callback)(nghttp2_session *session, const nghttp2_frame *frame, size_t max_payloadlen, void *user_data)
 
     
     Callback function invoked when the library asks application how
@@ -903,15 +933,16 @@ Types (structs, unions and typedefs)
     *frame*.  The application must choose the total length of payload
     including padded bytes in range [frame->hd.length, max_payloadlen],
     inclusive.  Choosing number not in this range will be treated as
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  Returning
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  Returning
     ``frame->hd.length`` means no padding is added.  Returning
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE` will make
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will make
     `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_select_padding_callback()`.
-.. type:: typedef ssize_t (*nghttp2_data_source_read_length_callback)( nghttp2_session *session, uint8_t frame_type, int32_t stream_id, int32_t session_remote_window_size, int32_t stream_remote_window_size, uint32_t remote_max_frame_size, void *user_data)
+.. type:: ssize_t (*nghttp2_data_source_read_length_callback)( nghttp2_session *session, uint8_t frame_type, int32_t stream_id, int32_t session_remote_window_size, int32_t stream_remote_window_size, uint32_t remote_max_frame_size, void *user_data)
 
     
     Callback function invoked when library wants to get max length of
@@ -921,20 +952,21 @@ Types (structs, unions and typedefs)
     *remote_max_frame_size*)].  If a value greater than this range is
     returned than the max allow value will be used.  Returning a value
     smaller than this range is treated as
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  The *frame_type* is provided
-    for future extensibility and identifies the type of frame (see
-    :type:`nghttp2_frame_type`) for which to get the length for.
-    Currently supported frame types are: :macro:`NGHTTP2_DATA`.
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  The
+    *frame_type* is provided for future extensibility and identifies
+    the type of frame (see :type:`nghttp2_frame_type`) for which to get
+    the length for.  Currently supported frame types are:
+    :macro:`nghttp2_frame_type.NGHTTP2_DATA`.
     
     This callback can be used to control the length in bytes for which
     :type:`nghttp2_data_source_read_callback` is allowed to send to the
     remote endpoint.  This callback is optional.  Returning
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the entire session
-    failure.
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will signal the
+    entire session failure.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_data_source_read_length_callback()`.
-.. type:: typedef int (*nghttp2_on_begin_frame_callback)(nghttp2_session *session, const nghttp2_frame_hd *hd, void *user_data)
+.. type:: int (*nghttp2_on_begin_frame_callback)(nghttp2_session *session, const nghttp2_frame_hd *hd, void *user_data)
 
     
     Callback function invoked when a frame header is received.  The
@@ -951,11 +983,12 @@ Types (structs, unions and typedefs)
     The implementation of this function must return 0 if it succeeds.
     If nonzero value is returned, it is treated as fatal error and
     `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
     
     To set this callback to :type:`nghttp2_session_callbacks`, use
     `nghttp2_session_callbacks_set_on_begin_frame_callback()`.
-.. type:: typedef int (*nghttp2_on_extension_chunk_recv_callback)( nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data, size_t len, void *user_data)
+.. type:: int (*nghttp2_on_extension_chunk_recv_callback)( nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data, size_t len, void *user_data)
 
     
     Callback function invoked when chunk of extension frame payload is
@@ -965,15 +998,16 @@ Types (structs, unions and typedefs)
     The implementation of this function must return 0 if it succeeds.
     
     To abort processing this extension frame, return
-    :macro:`NGHTTP2_ERR_CANCEL`.
+    :macro:`nghttp2_error.NGHTTP2_ERR_CANCEL`.
     
     If fatal error occurred, application should return
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
     `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the
-    other values are returned, currently they are treated as
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
-.. type:: typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session, void **payload, const nghttp2_frame_hd *hd, void *user_data)
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+    values are returned, currently they are treated as
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+.. type:: int (*nghttp2_unpack_extension_callback)(nghttp2_session *session, void **payload, const nghttp2_frame_hd *hd, void *user_data)
 
     
     Callback function invoked when library asks the application to
@@ -997,15 +1031,16 @@ Types (structs, unions and typedefs)
     *\*payload*, and do its own mechanism to process extension frames.
     
     To abort processing this extension frame, return
-    :macro:`NGHTTP2_ERR_CANCEL`.
+    :macro:`nghttp2_error.NGHTTP2_ERR_CANCEL`.
     
     If fatal error occurred, application should return
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
     `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the
-    other values are returned, currently they are treated as
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
-.. type:: typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session, uint8_t *buf, size_t len, const nghttp2_frame *frame, void *user_data)
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+    values are returned, currently they are treated as
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+.. type:: ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session, uint8_t *buf, size_t len, const nghttp2_frame *frame, void *user_data)
 
     
     Callback function invoked when library asks the application to pack
@@ -1020,18 +1055,19 @@ Types (structs, unions and typedefs)
     bytes written into *buf* when it succeeds.
     
     To abort processing this extension frame, return
-    :macro:`NGHTTP2_ERR_CANCEL`, and
+    :macro:`nghttp2_error.NGHTTP2_ERR_CANCEL`, and
     :type:`nghttp2_on_frame_not_send_callback` will be invoked.
     
     If fatal error occurred, application should return
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
     `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
-    immediately return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the
-    other values are returned, currently they are treated as
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the return value is
-    strictly larger than *len*, it is treated as
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.
-.. type:: typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg, size_t len, void *user_data)
+    immediately return
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+    values are returned, currently they are treated as
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the return
+    value is strictly larger than *len*, it is treated as
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+.. type:: int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg, size_t len, void *user_data)
 
     
     Callback function invoked when library provides the error message
@@ -1049,13 +1085,13 @@ Types (structs, unions and typedefs)
     
     Normally, application should return 0 from this callback.  If fatal
     error occurred while doing something in this callback, application
-    should return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
-    library will return immediately with return value
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  Currently, if nonzero value
-    is returned from this callback, they are treated as
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
-    rely on this details.
-.. type:: typedef int (*nghttp2_error_callback2)(nghttp2_session *session, int lib_error_code, const char *msg, size_t len, void *user_data)
+    should return :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+    In this case, library will return immediately with return value
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  Currently, if
+    nonzero value is returned from this callback, they are treated as
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, but application
+    should not rely on this details.
+.. type:: int (*nghttp2_error_callback2)(nghttp2_session *session, int lib_error_code, const char *msg, size_t len, void *user_data)
 
     
     Callback function invoked when library provides the error code, and
@@ -1071,12 +1107,12 @@ Types (structs, unions and typedefs)
     
     Normally, application should return 0 from this callback.  If fatal
     error occurred while doing something in this callback, application
-    should return :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
-    library will return immediately with return value
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`.  Currently, if nonzero value
-    is returned from this callback, they are treated as
-    :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
-    rely on this details.
+    should return :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+    In this case, library will return immediately with return value
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  Currently, if
+    nonzero value is returned from this callback, they are treated as
+    :macro:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, but application
+    should not rely on this details.
 .. type:: nghttp2_session_callbacks
 
     
@@ -1084,22 +1120,22 @@ Types (structs, unions and typedefs)
     this structure are intentionally hidden from the public API.
 
 
-.. type:: typedef void *(*nghttp2_malloc)(size_t size, void *mem_user_data)
+.. type:: void *(*nghttp2_malloc)(size_t size, void *mem_user_data)
 
     
     Custom memory allocator to replace malloc().  The *mem_user_data*
     is the mem_user_data member of :type:`nghttp2_mem` structure.
-.. type:: typedef void (*nghttp2_free)(void *ptr, void *mem_user_data)
+.. type:: void (*nghttp2_free)(void *ptr, void *mem_user_data)
 
     
     Custom memory allocator to replace free().  The *mem_user_data* is
     the mem_user_data member of :type:`nghttp2_mem` structure.
-.. type:: typedef void *(*nghttp2_calloc)(size_t nmemb, size_t size, void *mem_user_data)
+.. type:: void *(*nghttp2_calloc)(size_t nmemb, size_t size, void *mem_user_data)
 
     
     Custom memory allocator to replace calloc().  The *mem_user_data*
     is the mem_user_data member of :type:`nghttp2_mem` structure.
-.. type:: typedef void *(*nghttp2_realloc)(void *ptr, size_t size, void *mem_user_data)
+.. type:: void *(*nghttp2_realloc)(void *ptr, size_t size, void *mem_user_data)
 
     
     Custom memory allocator to replace realloc().  The *mem_user_data*
@@ -1174,8 +1210,8 @@ Types (structs, unions and typedefs)
     extension to HTTP/2.  If this frame is received, and
     `nghttp2_option_set_user_recv_extension_type()` is not set, and
     `nghttp2_option_set_builtin_recv_extension_type()` is set for
-    :macro:`NGHTTP2_ALTSVC`, ``nghttp2_extension.payload`` will point to
-    this struct.
+    :macro:`nghttp2_frame_type.NGHTTP2_ALTSVC`,
+    ``nghttp2_extension.payload`` will point to this struct.
     
     It has the following members:
 
@@ -1217,8 +1253,8 @@ Types (structs, unions and typedefs)
     If this frame is received, and
     `nghttp2_option_set_user_recv_extension_type()` is not set, and
     `nghttp2_option_set_builtin_recv_extension_type()` is set for
-    :macro:`NGHTTP2_ORIGIN`, ``nghttp2_extension.payload`` will point to
-    this struct.
+    :macro:`nghttp2_frame_type.NGHTTP2_ORIGIN`,
+    ``nghttp2_extension.payload`` will point to this struct.
     
     It has the following members:
 
@@ -1248,7 +1284,7 @@ Types (structs, unions and typedefs)
     structure are intentionally hidden from the public API.
 
 
-.. type:: typedef void (*nghttp2_debug_vprintf_callback)(const char *format, va_list args)
+.. type:: void (*nghttp2_debug_vprintf_callback)(const char *format, va_list args)
 
     
     Callback function invoked when the library outputs debug logging.
index b22279d..979d7d2 100644 (file)
@@ -35,6 +35,7 @@ AM_CPPFLAGS = \
        @LIBEVENT_OPENSSL_CFLAGS@ \
        @OPENSSL_CFLAGS@ \
        @DEFS@
+AM_LDFLAGS = @LIBTOOL_LDFLAGS@
 LDADD = $(top_builddir)/lib/libnghttp2.la \
        $(top_builddir)/third-party/liburl-parser.la \
        @LIBEVENT_OPENSSL_LIBS@ \
index a47209d..40428ad 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -289,8 +289,6 @@ am__define_uniq_tagged_files = \
   unique=`for i in $$list; do \
     if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
   done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
@@ -307,11 +305,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -330,8 +331,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -342,9 +346,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -353,9 +360,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -393,8 +409,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -485,6 +502,7 @@ EXTRA_DIST = CMakeLists.txt
 @ENABLE_EXAMPLES_TRUE@ @OPENSSL_CFLAGS@ \
 @ENABLE_EXAMPLES_TRUE@ @DEFS@
 
+@ENABLE_EXAMPLES_TRUE@AM_LDFLAGS = @LIBTOOL_LDFLAGS@
 @ENABLE_EXAMPLES_TRUE@LDADD = $(top_builddir)/lib/libnghttp2.la \
 @ENABLE_EXAMPLES_TRUE@ $(top_builddir)/third-party/liburl-parser.la \
 @ENABLE_EXAMPLES_TRUE@ @LIBEVENT_OPENSSL_LIBS@ \
@@ -779,7 +797,6 @@ cscopelist-am: $(am__tagged_files)
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
index 2d3c4c5..6cc3fdd 100644 (file)
@@ -380,6 +380,10 @@ static void init_ssl_ctx(SSL_CTX *ssl_ctx) {
 #ifndef OPENSSL_NO_NEXTPROTONEG
   SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
 #endif /* !OPENSSL_NO_NEXTPROTONEG */
+
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+  SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
+#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
 }
 
 static void ssl_handshake(SSL *ssl, int fd) {
@@ -544,7 +548,7 @@ static void fetch_uri(const struct URI *uri) {
   if (fd == -1) {
     die("Could not open file descriptor");
   }
-  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+  ssl_ctx = SSL_CTX_new(TLS_client_method());
   if (ssl_ctx == NULL) {
     dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL));
   }
@@ -715,8 +719,18 @@ int main(int argc, char **argv) {
   act.sa_handler = SIG_IGN;
   sigaction(SIGPIPE, &act, 0);
 
+#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+  /* No explicit initialization is required. */
+#elif defined(OPENSSL_IS_BORINGSSL)
+  CRYPTO_library_init();
+#else  /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) &&                          \
+          !defined(OPENSSL_IS_BORINGSSL) */
+  OPENSSL_config(NULL);
   SSL_load_error_strings();
   SSL_library_init();
+  OpenSSL_add_all_algorithms();
+#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) &&                          \
+          !defined(OPENSSL_IS_BORINGSSL) */
 
   rv = parse_uri(&uri, argv[1]);
   if (rv != 0) {
index 63f3ea1..df1cb92 100644 (file)
@@ -44,7 +44,7 @@ static void deflate(nghttp2_hd_deflater *deflater,
 static int inflate_header_block(nghttp2_hd_inflater *inflater, uint8_t *in,
                                 size_t inlen, int final);
 
-int main() {
+int main(void) {
   int rv;
   nghttp2_hd_deflater *deflater;
   nghttp2_hd_inflater *inflater;
index f42cbdb..2debd7b 100644 (file)
@@ -328,7 +328,7 @@ static int select_next_proto_cb(SSL *ssl, unsigned char **out,
 /* Create SSL_CTX. */
 static SSL_CTX *create_ssl_ctx(void) {
   SSL_CTX *ssl_ctx;
-  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+  ssl_ctx = SSL_CTX_new(TLS_client_method());
   if (!ssl_ctx) {
     errx(1, "Could not create SSL/TLS context: %s",
          ERR_error_string(ERR_get_error(), NULL));
@@ -617,8 +617,18 @@ int main(int argc, char **argv) {
   act.sa_handler = SIG_IGN;
   sigaction(SIGPIPE, &act, NULL);
 
+#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+  /* No explicit initialization is required. */
+#elif defined(OPENSSL_IS_BORINGSSL)
+  CRYPTO_library_init();
+#else  /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) &&                          \
+          !defined(OPENSSL_IS_BORINGSSL) */
+  OPENSSL_config(NULL);
   SSL_load_error_strings();
   SSL_library_init();
+  OpenSSL_add_all_algorithms();
+#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) &&                          \
+          !defined(OPENSSL_IS_BORINGSSL) */
 
   run(argv[1]);
   return 0;
index a553617..9f4e128 100644 (file)
@@ -142,9 +142,8 @@ static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
 /* Create SSL_CTX. */
 static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
   SSL_CTX *ssl_ctx;
-  EC_KEY *ecdh;
 
-  ssl_ctx = SSL_CTX_new(SSLv23_server_method());
+  ssl_ctx = SSL_CTX_new(TLS_server_method());
   if (!ssl_ctx) {
     errx(1, "Could not create SSL/TLS context: %s",
          ERR_error_string(ERR_get_error(), NULL));
@@ -153,14 +152,23 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
                       SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
                           SSL_OP_NO_COMPRESSION |
                           SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
-
-  ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
-  if (!ecdh) {
-    errx(1, "EC_KEY_new_by_curv_name failed: %s",
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+  if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) {
+    errx(1, "SSL_CTX_set1_curves_list failed: %s",
          ERR_error_string(ERR_get_error(), NULL));
   }
-  SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
-  EC_KEY_free(ecdh);
+#else  /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
+  {
+    EC_KEY *ecdh;
+    ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+    if (!ecdh) {
+      errx(1, "EC_KEY_new_by_curv_name failed: %s",
+           ERR_error_string(ERR_get_error(), NULL));
+    }
+    SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
+    EC_KEY_free(ecdh);
+  }
+#endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
 
   if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) != 1) {
     errx(1, "Could not read private key file %s", key_file);
@@ -809,8 +817,18 @@ int main(int argc, char **argv) {
   act.sa_handler = SIG_IGN;
   sigaction(SIGPIPE, &act, NULL);
 
+#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+  /* No explicit initialization is required. */
+#elif defined(OPENSSL_IS_BORINGSSL)
+  CRYPTO_library_init();
+#else  /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) &&                          \
+          !defined(OPENSSL_IS_BORINGSSL) */
+  OPENSSL_config(NULL);
   SSL_load_error_strings();
   SSL_library_init();
+  OpenSSL_add_all_algorithms();
+#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) &&                          \
+          !defined(OPENSSL_IS_BORINGSSL) */
 
   run(argv[1], argv[2], argv[3]);
   return 0;
index 8175c64..ec298b5 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2018-03-11.20; # UTC
+scriptversion=2020-11-14.01; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -69,6 +69,11 @@ posix_mkdir=
 # Desired mode of installed file.
 mode=0755
 
+# Create dirs (including intermediate dirs) using mode 755.
+# This is like GNU 'install' as of coreutils 8.32 (2020).
+mkdir_umask=22
+
+backupsuffix=
 chgrpcmd=
 chmodcmd=$chmodprog
 chowncmd=
@@ -99,18 +104,28 @@ Options:
      --version  display version info and exit.
 
   -c            (ignored)
-  -C            install only if different (preserve the last data modification time)
+  -C            install only if different (preserve data modification time)
   -d            create directories instead of installing files.
   -g GROUP      $chgrpprog installed files to GROUP.
   -m MODE       $chmodprog installed files to MODE.
   -o USER       $chownprog installed files to USER.
+  -p            pass -p to $cpprog.
   -s            $stripprog installed files.
+  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
   -t DIRECTORY  install into DIRECTORY.
   -T            report an error if DSTFILE is a directory.
 
 Environment variables override the default commands:
   CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
   RMPROG STRIPPROG
+
+By default, rm is invoked with -f; when overridden with RMPROG,
+it's up to you to specify -f if you want it.
+
+If -S is not specified, no backups are attempted.
+
+Email bug reports to bug-automake@gnu.org.
+Automake home page: https://www.gnu.org/software/automake/
 "
 
 while test $# -ne 0; do
@@ -137,8 +152,13 @@ while test $# -ne 0; do
     -o) chowncmd="$chownprog $2"
         shift;;
 
+    -p) cpprog="$cpprog -p";;
+
     -s) stripcmd=$stripprog;;
 
+    -S) backupsuffix="$2"
+        shift;;
+
     -t)
         is_target_a_directory=always
         dst_arg=$2
@@ -255,6 +275,10 @@ do
     dstdir=$dst
     test -d "$dstdir"
     dstdir_status=$?
+    # Don't chown directories that already exist.
+    if test $dstdir_status = 0; then
+      chowncmd=""
+    fi
   else
 
     # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
@@ -301,22 +325,6 @@ do
   if test $dstdir_status != 0; then
     case $posix_mkdir in
       '')
-        # Create intermediate dirs using mode 755 as modified by the umask.
-        # This is like FreeBSD 'install' as of 1997-10-28.
-        umask=`umask`
-        case $stripcmd.$umask in
-          # Optimize common cases.
-          *[2367][2367]) mkdir_umask=$umask;;
-          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
-          *[0-7])
-            mkdir_umask=`expr $umask + 22 \
-              - $umask % 100 % 40 + $umask % 20 \
-              - $umask % 10 % 4 + $umask % 2
-            `;;
-          *) mkdir_umask=$umask,go-w;;
-        esac
-
         # With -d, create the new directory with the user-specified mode.
         # Otherwise, rely on $mkdir_umask.
         if test -n "$dir_arg"; then
@@ -326,52 +334,49 @@ do
         fi
 
         posix_mkdir=false
-        case $umask in
-          *[123567][0-7][0-7])
-            # POSIX mkdir -p sets u+wx bits regardless of umask, which
-            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
-            ;;
-          *)
-            # Note that $RANDOM variable is not portable (e.g. dash);  Use it
-            # here however when possible just to lower collision chance.
-            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
-
-            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
-
-            # Because "mkdir -p" follows existing symlinks and we likely work
-            # directly in world-writeable /tmp, make sure that the '$tmpdir'
-            # directory is successfully created first before we actually test
-            # 'mkdir -p' feature.
-            if (umask $mkdir_umask &&
-                $mkdirprog $mkdir_mode "$tmpdir" &&
-                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
-            then
-              if test -z "$dir_arg" || {
-                   # Check for POSIX incompatibilities with -m.
-                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                   # other-writable bit of parent directory when it shouldn't.
-                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                   test_tmpdir="$tmpdir/a"
-                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
-                   case $ls_ld_tmpdir in
-                     d????-?r-*) different_mode=700;;
-                     d????-?--*) different_mode=755;;
-                     *) false;;
-                   esac &&
-                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
-                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
-                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
-                   }
-                 }
-              then posix_mkdir=:
-              fi
-              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
-            else
-              # Remove any dirs left behind by ancient mkdir implementations.
-              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
-            fi
-            trap '' 0;;
-        esac;;
+       # The $RANDOM variable is not portable (e.g., dash).  Use it
+       # here however when possible just to lower collision chance.
+       tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+
+       trap '
+         ret=$?
+         rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
+         exit $ret
+       ' 0
+
+       # Because "mkdir -p" follows existing symlinks and we likely work
+       # directly in world-writeable /tmp, make sure that the '$tmpdir'
+       # directory is successfully created first before we actually test
+       # 'mkdir -p'.
+       if (umask $mkdir_umask &&
+           $mkdirprog $mkdir_mode "$tmpdir" &&
+           exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+       then
+         if test -z "$dir_arg" || {
+              # Check for POSIX incompatibilities with -m.
+              # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+              # other-writable bit of parent directory when it shouldn't.
+              # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+              test_tmpdir="$tmpdir/a"
+              ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+              case $ls_ld_tmpdir in
+                d????-?r-*) different_mode=700;;
+                d????-?--*) different_mode=755;;
+                *) false;;
+              esac &&
+              $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+                ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+                test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+              }
+            }
+         then posix_mkdir=:
+         fi
+         rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
+       else
+         # Remove any dirs left behind by ancient mkdir implementations.
+         rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
+       fi
+       trap '' 0;;
     esac
 
     if
@@ -382,7 +387,7 @@ do
     then :
     else
 
-      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # mkdir does not conform to POSIX,
       # or it failed possibly due to a race condition.  Create the
       # directory the slow way, step by step, checking for races as we go.
 
@@ -411,7 +416,7 @@ do
           prefixes=
         else
           if $posix_mkdir; then
-            (umask=$mkdir_umask &&
+            (umask $mkdir_umask &&
              $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
             # Don't fail if two instances are running concurrently.
             test -d "$prefix" || exit 1
@@ -451,7 +456,18 @@ do
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
 
     # Copy the file name to the temp name.
-    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+    (umask $cp_umask &&
+     { test -z "$stripcmd" || {
+        # Create $dsttmp read-write so that cp doesn't create it read-only,
+        # which would cause strip to fail.
+        if test -z "$doit"; then
+          : >"$dsttmp" # No need to fork-exec 'touch'.
+        else
+          $doit touch "$dsttmp"
+        fi
+       }
+     } &&
+     $doit_exec $cpprog "$src" "$dsttmp") &&
 
     # and set any options; do chmod last to preserve setuid bits.
     #
@@ -477,6 +493,13 @@ do
     then
       rm -f "$dsttmp"
     else
+      # If $backupsuffix is set, and the file being installed
+      # already exists, attempt a backup.  Don't worry if it fails,
+      # e.g., if mv doesn't support -f.
+      if test -n "$backupsuffix" && test -f "$dst"; then
+        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
+      fi
+
       # Rename the file to the real destination.
       $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
 
@@ -491,9 +514,9 @@ do
         # file should still install successfully.
         {
           test ! -f "$dst" ||
-          $doit $rmcmd -f "$dst" 2>/dev/null ||
+          $doit $rmcmd "$dst" 2>/dev/null ||
           { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
           } ||
           { echo "$0: cannot unlink or rename $dst" >&2
             (exit 1); exit 1
index 539599d..0e9c7c2 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -167,11 +167,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -190,8 +193,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -202,9 +208,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -213,9 +222,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -253,8 +271,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -399,7 +418,6 @@ ctags CTAGS:
 
 cscope cscopelist:
 
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
index 3d41677..9eb80e6 100644 (file)
@@ -1171,3 +1171,31 @@ Content-Length: 1000000
                t.Errorf("status: %v; want %v", got, want)
        }
 }
+
+// TestH1H1ChunkedEndsPrematurely tests that an HTTP/1.1 request fails
+// if the backend chunked encoded response ends prematurely.
+func TestH1H1ChunkedEndsPrematurely(t *testing.T) {
+       st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
+               hj, ok := w.(http.Hijacker)
+               if !ok {
+                       http.Error(w, "Could not hijack the connection", http.StatusInternalServerError)
+                       return
+               }
+               conn, bufrw, err := hj.Hijack()
+               if err != nil {
+                       http.Error(w, err.Error(), http.StatusInternalServerError)
+                       return
+               }
+               defer conn.Close()
+               bufrw.WriteString("HTTP/1.1 200\r\nTransfer-Encoding: chunked\r\n\r\n")
+               bufrw.Flush()
+       })
+       defer st.Close()
+
+       _, err := st.http1(requestParam{
+               name: "TestH1H1ChunkedEndsPrematurely",
+       })
+       if err == nil {
+               t.Fatal("st.http1() should fail")
+       }
+}
index 84646fa..a856f8f 100644 (file)
@@ -565,7 +565,7 @@ func TestH2H1BadResponseCL(t *testing.T) {
                t.Fatalf("Error st.http2() = %v", err)
        }
 
-       want := http2.ErrCodeProtocol
+       want := http2.ErrCodeInternal
        if res.errCode != want {
                t.Errorf("res.errCode = %v; want %v", res.errCode, want)
        }
@@ -2838,3 +2838,35 @@ func TestH2ResponseBeforeRequestEnd(t *testing.T) {
                t.Errorf("res.status: %v; want %v", got, want)
        }
 }
+
+// TestH2H1ChunkedEndsPrematurely tests that a stream is reset if the
+// backend chunked encoded response ends prematurely.
+func TestH2H1ChunkedEndsPrematurely(t *testing.T) {
+       st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
+               hj, ok := w.(http.Hijacker)
+               if !ok {
+                       http.Error(w, "Could not hijack the connection", http.StatusInternalServerError)
+                       return
+               }
+               conn, bufrw, err := hj.Hijack()
+               if err != nil {
+                       http.Error(w, err.Error(), http.StatusInternalServerError)
+                       return
+               }
+               defer conn.Close()
+               bufrw.WriteString("HTTP/1.1 200\r\nTransfer-Encoding: chunked\r\n\r\n")
+               bufrw.Flush()
+       })
+       defer st.Close()
+
+       res, err := st.http2(requestParam{
+               name: "TestH2H1ChunkedEndsPrematurely",
+       })
+       if err != nil {
+               t.Fatalf("Error st.http2() = %v", err)
+       }
+
+       if got, want := res.errCode, http2.ErrCodeInternal; got != want {
+               t.Errorf("res.errCode = %v; want %v", got, want)
+       }
+}
index a2a3d59..1586a45 100644 (file)
@@ -5,8 +5,9 @@ if [ -d "$libdir/.libs" ]; then
     libdir="$libdir/.libs"
 fi
 
-export CGO_CFLAGS="-I/mnt/nghttp2/lib/includes -I/mnt/nghttp2/lib/includes"
-export CGO_LDFLAGS="-L$libdir"
+export CGO_CFLAGS="-I/mnt/nghttp2/lib/includes -I/mnt/nghttp2/lib/includes -g -O2"
+export CGO_CPPFLAGS=""
+export CGO_LDFLAGS="-L$libdir "
 export LD_LIBRARY_PATH="$libdir"
 export GODEBUG=cgocheck=0
 "$@"
index c0f6b48..7177200 100644 (file)
@@ -5,8 +5,9 @@ if [ -d "$libdir/.libs" ]; then
     libdir="$libdir/.libs"
 fi
 
-export CGO_CFLAGS="-I@abs_top_srcdir@/lib/includes -I@abs_top_builddir@/lib/includes"
-export CGO_LDFLAGS="-L$libdir"
+export CGO_CFLAGS="-I@abs_top_srcdir@/lib/includes -I@abs_top_builddir@/lib/includes @CFLAGS@"
+export CGO_CPPFLAGS="@CPPFLAGS@"
+export CGO_LDFLAGS="-L$libdir @LDFLAGS@"
 export LD_LIBRARY_PATH="$libdir"
 export GODEBUG=cgocheck=0
 "$@"
index 24a5bd6..1e1f248 100644 (file)
@@ -27,6 +27,7 @@ EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
 AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
 AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
        @DEFS@
+AM_LDFLAGS = @LIBTOOL_LDFLAGS@
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libnghttp2.pc
@@ -68,5 +69,5 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
        nghttp2_debug.h
 
 libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
-libnghttp2_la_LDFLAGS = -no-undefined \
+libnghttp2_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \
        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
index d94da88..5653774 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -261,8 +261,6 @@ am__define_uniq_tagged_files = \
   unique=`for i in $$list; do \
     if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
   done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
 DIST_SUBDIRS = $(SUBDIRS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libnghttp2.pc.in \
        $(top_srcdir)/depcomp
@@ -306,11 +304,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -329,8 +330,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -341,9 +345,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -352,9 +359,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -392,8 +408,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -486,6 +503,7 @@ AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
 AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
        @DEFS@
 
+AM_LDFLAGS = @LIBTOOL_LDFLAGS@
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libnghttp2.pc
 DISTCLEANFILES = $(pkgconfig_DATA)
@@ -524,7 +542,7 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
        nghttp2_debug.h
 
 libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
-libnghttp2_la_LDFLAGS = -no-undefined \
+libnghttp2_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \
        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
 
 all: all-recursive
@@ -785,7 +803,6 @@ cscopelist-am: $(am__tagged_files)
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
index f12b8f6..327e523 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -197,8 +197,6 @@ am__define_uniq_tagged_files = \
   unique=`for i in $$list; do \
     if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
   done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
 am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
@@ -215,11 +213,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -238,8 +239,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -250,9 +254,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -261,9 +268,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -301,8 +317,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -497,7 +514,6 @@ cscopelist-am: $(am__tagged_files)
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
index 9be6eea..04321a6 100644 (file)
@@ -411,12 +411,12 @@ typedef enum {
    */
   NGHTTP2_ERR_TOO_MANY_SETTINGS = -537,
   /**
-   * The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is
-   * under unexpected condition and processing was terminated (e.g.,
-   * out of memory).  If application receives this error code, it must
-   * stop using that :type:`nghttp2_session` object and only allowed
-   * operation for that object is deallocate it using
-   * `nghttp2_session_del()`.
+   * The errors < :enum:`nghttp2_error.NGHTTP2_ERR_FATAL` mean that
+   * the library is under unexpected condition and processing was
+   * terminated (e.g., out of memory).  If application receives this
+   * error code, it must stop using that :type:`nghttp2_session`
+   * object and only allowed operation for that object is deallocate
+   * it using `nghttp2_session_del()`.
    */
   NGHTTP2_ERR_FATAL = -900,
   /**
@@ -545,9 +545,9 @@ typedef struct {
    * :type:`nghttp2_on_frame_send_callback`, and
    * :type:`nghttp2_on_frame_not_send_callback`), it may not be
    * NULL-terminated if header field is passed from application with
-   * the flag :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`).  When application
-   * is constructing this struct, |name| is not required to be
-   * NULL-terminated.
+   * the flag :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`).
+   * When application is constructing this struct, |name| is not
+   * required to be NULL-terminated.
    */
   uint8_t *name;
   /**
@@ -558,9 +558,9 @@ typedef struct {
    * :type:`nghttp2_on_frame_send_callback`, and
    * :type:`nghttp2_on_frame_not_send_callback`), it may not be
    * NULL-terminated if header field is passed from application with
-   * the flag :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE`).  When
-   * application is constructing this struct, |value| is not required
-   * to be NULL-terminated.
+   * the flag :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE`).
+   * When application is constructing this struct, |value| is not
+   * required to be NULL-terminated.
    */
   uint8_t *value;
   /**
@@ -717,8 +717,8 @@ typedef enum {
  *
  * Default maximum number of incoming concurrent streams.  Use
  * `nghttp2_submit_settings()` with
- * :enum:`NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` to change the
- * maximum number of incoming concurrent streams.
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS`
+ * to change the maximum number of incoming concurrent streams.
  *
  * .. note::
  *
@@ -872,38 +872,41 @@ typedef enum {
  * The implementation of this function must read at most |length|
  * bytes of data from |source| (or possibly other places) and store
  * them in |buf| and return number of data stored in |buf|.  If EOF is
- * reached, set :enum:`NGHTTP2_DATA_FLAG_EOF` flag in |*data_flags|.
+ * reached, set :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag
+ * in |*data_flags|.
  *
  * Sometime it is desirable to avoid copying data into |buf| and let
  * application to send data directly.  To achieve this, set
- * :enum:`NGHTTP2_DATA_FLAG_NO_COPY` to |*data_flags| (and possibly
- * other flags, just like when we do copy), and return the number of
- * bytes to send without copying data into |buf|.  The library, seeing
- * :enum:`NGHTTP2_DATA_FLAG_NO_COPY`, will invoke
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` to
+ * |*data_flags| (and possibly other flags, just like when we do
+ * copy), and return the number of bytes to send without copying data
+ * into |buf|.  The library, seeing
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY`, will invoke
  * :type:`nghttp2_send_data_callback`.  The application must send
  * complete DATA frame in that callback.
  *
  * If this callback is set by `nghttp2_submit_request()`,
  * `nghttp2_submit_response()` or `nghttp2_submit_headers()` and
  * `nghttp2_submit_data()` with flag parameter
- * :enum:`NGHTTP2_FLAG_END_STREAM` set, and
- * :enum:`NGHTTP2_DATA_FLAG_EOF` flag is set to |*data_flags|, DATA
- * frame will have END_STREAM flag set.  Usually, this is expected
- * behaviour and all are fine.  One exception is send trailer fields.
- * You cannot send trailer fields after sending frame with END_STREAM
- * set.  To avoid this problem, one can set
- * :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM` along with
- * :enum:`NGHTTP2_DATA_FLAG_EOF` to signal the library not to set
- * END_STREAM in DATA frame.  Then application can use
- * `nghttp2_submit_trailer()` to send trailer fields.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` set, and
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag is set to
+ * |*data_flags|, DATA frame will have END_STREAM flag set.  Usually,
+ * this is expected behaviour and all are fine.  One exception is send
+ * trailer fields.  You cannot send trailer fields after sending frame
+ * with END_STREAM set.  To avoid this problem, one can set
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM` along
+ * with :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` to signal the
+ * library not to set END_STREAM in DATA frame.  Then application can
+ * use `nghttp2_submit_trailer()` to send trailer fields.
  * `nghttp2_submit_trailer()` can be called inside this callback.
  *
  * If the application wants to postpone DATA frames (e.g.,
  * asynchronous I/O, or reading data blocks for long time), it is
- * achieved by returning :enum:`NGHTTP2_ERR_DEFERRED` without reading
- * any data in this invocation.  The library removes DATA frame from
- * the outgoing queue temporarily.  To move back deferred DATA frame
- * to outgoing queue, call `nghttp2_session_resume_data()`.
+ * achieved by returning :enum:`nghttp2_error.NGHTTP2_ERR_DEFERRED`
+ * without reading any data in this invocation.  The library removes
+ * DATA frame from the outgoing queue temporarily.  To move back
+ * deferred DATA frame to outgoing queue, call
+ * `nghttp2_session_resume_data()`.
  *
  * By default, |length| is limited to 16KiB at maximum.  If peer
  * allows larger frames, application can enlarge transmission buffer
@@ -912,16 +915,17 @@ typedef enum {
  *
  * If the application just wants to return from
  * `nghttp2_session_send()` or `nghttp2_session_mem_send()` without
- * sending anything, return :enum:`NGHTTP2_ERR_PAUSE`.
+ * sending anything, return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`.
  *
  * In case of error, there are 2 choices. Returning
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close the stream
- * by issuing RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`.  If a
- * different error code is desirable, use
- * `nghttp2_submit_rst_stream()` with a desired error code and then
- * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  Returning
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the entire session
- * failure.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+ * close the stream by issuing RST_STREAM with
+ * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`.  If a different
+ * error code is desirable, use `nghttp2_submit_rst_stream()` with a
+ * desired error code and then return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * Returning :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will
+ * signal the entire session failure.
  */
 typedef ssize_t (*nghttp2_data_source_read_callback)(
     nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length,
@@ -1301,8 +1305,9 @@ typedef union {
  * |length| bytes of data stored in |data|.  The |flags| is currently
  * not used and always 0. It must return the number of bytes sent if
  * it succeeds.  If it cannot send any single byte without blocking,
- * it must return :enum:`NGHTTP2_ERR_WOULDBLOCK`.  For other errors,
- * it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  The
+ * it must return :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`.  For
+ * other errors, it must return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  The
  * |user_data| pointer is the third argument passed in to the call to
  * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
  *
@@ -1330,9 +1335,10 @@ typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session,
 /**
  * @functypedef
  *
- * Callback function invoked when :enum:`NGHTTP2_DATA_FLAG_NO_COPY` is
- * used in :type:`nghttp2_data_source_read_callback` to send complete
- * DATA frame.
+ * Callback function invoked when
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in
+ * :type:`nghttp2_data_source_read_callback` to send complete DATA
+ * frame.
  *
  * The |frame| is a DATA frame to send.  The |framehd| is the
  * serialized frame header (9 bytes). The |length| is the length of
@@ -1350,21 +1356,22 @@ typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session,
  * If all data were written successfully, return 0.
  *
  * If it cannot send any data at all, just return
- * :enum:`NGHTTP2_ERR_WOULDBLOCK`; the library will call this callback
- * with the same parameters later (It is recommended to send complete
- * DATA frame at once in this function to deal with error; if partial
- * frame data has already sent, it is impossible to send another data
- * in that state, and all we can do is tear down connection).  When
- * data is fully processed, but application wants to make
- * `nghttp2_session_mem_send()` or `nghttp2_session_send()` return
- * immediately without processing next frames, return
- * :enum:`NGHTTP2_ERR_PAUSE`.  If application decided to reset this
- * stream, return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`; the library will call
+ * this callback with the same parameters later (It is recommended to
+ * send complete DATA frame at once in this function to deal with
+ * error; if partial frame data has already sent, it is impossible to
+ * send another data in that state, and all we can do is tear down
+ * connection).  When data is fully processed, but application wants
+ * to make `nghttp2_session_mem_send()` or `nghttp2_session_send()`
+ * return immediately without processing next frames, return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`.  If application decided to
+ * reset this stream, return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then
  * the library will send RST_STREAM with INTERNAL_ERROR as error code.
  * The application can also return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, which will result in
- * connection closure.  Returning any other value is treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which will
+ * result in connection closure.  Returning any other value is treated
+ * as :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
  */
 typedef int (*nghttp2_send_data_callback)(nghttp2_session *session,
                                           nghttp2_frame *frame,
@@ -1381,11 +1388,13 @@ typedef int (*nghttp2_send_data_callback)(nghttp2_session *session,
  * currently not used and always 0.  It must return the number of
  * bytes written in |buf| if it succeeds.  If it cannot read any
  * single byte without blocking, it must return
- * :enum:`NGHTTP2_ERR_WOULDBLOCK`.  If it gets EOF before it reads any
- * single byte, it must return :enum:`NGHTTP2_ERR_EOF`.  For other
- * errors, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
- * Returning 0 is treated as :enum:`NGHTTP2_ERR_WOULDBLOCK`.  The
- * |user_data| pointer is the third argument passed in to the call to
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`.  If it gets EOF
+ * before it reads any single byte, it must return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_EOF`.  For other errors, it must
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * Returning 0 is treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`.  The |user_data|
+ * pointer is the third argument passed in to the call to
  * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
  *
  * This callback is required if the application uses
@@ -1429,7 +1438,8 @@ typedef ssize_t (*nghttp2_recv_callback)(nghttp2_session *session, uint8_t *buf,
  * The implementation of this function must return 0 if it succeeds.
  * If nonzero value is returned, it is treated as fatal error and
  * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_on_frame_recv_callback()`.
@@ -1457,7 +1467,8 @@ typedef int (*nghttp2_on_frame_recv_callback)(nghttp2_session *session,
  * The implementation of this function must return 0 if it succeeds.
  * If nonzero is returned, it is treated as fatal error and
  * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_on_invalid_frame_recv_callback()`.
@@ -1480,9 +1491,9 @@ typedef int (*nghttp2_on_invalid_frame_recv_callback)(
  * `nghttp2_session_server_new()`.
  *
  * If the application uses `nghttp2_session_mem_recv()`, it can return
- * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
- * return without processing further input bytes.  The memory by
- * pointed by the |data| is retained until
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
+ * `nghttp2_session_mem_recv()` return without processing further
+ * input bytes.  The memory by pointed by the |data| is retained until
  * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
  * The application must retain the input bytes which was used to
  * produce the |data| parameter, because it may refer to the memory
@@ -1491,7 +1502,8 @@ typedef int (*nghttp2_on_invalid_frame_recv_callback)(
  * The implementation of this function must return 0 if it succeeds.
  * If nonzero is returned, it is treated as fatal error, and
  * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_on_data_chunk_recv_callback()`.
@@ -1511,19 +1523,20 @@ typedef int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session,
  * `nghttp2_session_server_new()`.
  *
  * The implementation of this function must return 0 if it succeeds.
- * It can also return :enum:`NGHTTP2_ERR_CANCEL` to cancel the
- * transmission of the given frame.
+ * It can also return :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL` to
+ * cancel the transmission of the given frame.
  *
  * If there is a fatal error while executing this callback, the
- * implementation should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`,
- * which makes `nghttp2_session_send()` and
- * `nghttp2_session_mem_send()` functions immediately return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * implementation should return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which makes
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * If the other value is returned, it is treated as if
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned.  But the
- * implementation should not rely on this since the library may define
- * new return value to extend its capability.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
+ * But the implementation should not rely on this since the library
+ * may define new return value to extend its capability.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_before_frame_send_callback()`.
@@ -1542,7 +1555,8 @@ typedef int (*nghttp2_before_frame_send_callback)(nghttp2_session *session,
  * The implementation of this function must return 0 if it succeeds.
  * If nonzero is returned, it is treated as fatal error and
  * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_on_frame_send_callback()`.
@@ -1564,7 +1578,8 @@ typedef int (*nghttp2_on_frame_send_callback)(nghttp2_session *session,
  * The implementation of this function must return 0 if it succeeds.
  * If nonzero is returned, it is treated as fatal error and
  * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * `nghttp2_session_get_stream_user_data()` can be used to get
  * associated data.
@@ -1595,7 +1610,8 @@ typedef int (*nghttp2_on_frame_not_send_callback)(nghttp2_session *session,
  * If nonzero is returned, it is treated as fatal error and
  * `nghttp2_session_recv()`, `nghttp2_session_mem_recv()`,
  * `nghttp2_session_send()`, and `nghttp2_session_mem_send()`
- * functions immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * functions immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_on_stream_close_callback()`.
@@ -1613,10 +1629,11 @@ typedef int (*nghttp2_on_stream_close_callback)(nghttp2_session *session,
  * will be emitted by :type:`nghttp2_on_header_callback`.
  *
  * The ``frame->hd.flags`` may not have
- * :enum:`NGHTTP2_FLAG_END_HEADERS` flag set, which indicates that one
- * or more CONTINUATION frames are involved.  But the application does
- * not need to care about that because the header name/value pairs are
- * emitted transparently regardless of CONTINUATION frames.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_HEADERS` flag set, which
+ * indicates that one or more CONTINUATION frames are involved.  But
+ * the application does not need to care about that because the header
+ * name/value pairs are emitted transparently regardless of
+ * CONTINUATION frames.
  *
  * The server applications probably create an object to store
  * information about new stream if ``frame->hd.type ==
@@ -1639,26 +1656,31 @@ typedef int (*nghttp2_on_stream_close_callback)(nghttp2_session *session,
  * trailer fields also has ``frame->headers.cat ==
  * NGHTTP2_HCAT_HEADERS`` which does not contain any status code.
  *
- * Returning :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close
- * the stream (promised stream if frame is PUSH_PROMISE) by issuing
- * RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`.  In this case,
+ * Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+ * close the stream (promised stream if frame is PUSH_PROMISE) by
+ * issuing RST_STREAM with
+ * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`.  In this case,
  * :type:`nghttp2_on_header_callback` and
  * :type:`nghttp2_on_frame_recv_callback` will not be invoked.  If a
  * different error code is desirable, use
  * `nghttp2_submit_rst_stream()` with a desired error code and then
- * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  Again, use
- * ``frame->push_promise.promised_stream_id`` as stream_id parameter
- * in `nghttp2_submit_rst_stream()` if frame is PUSH_PROMISE.
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * Again, use ``frame->push_promise.promised_stream_id`` as stream_id
+ * parameter in `nghttp2_submit_rst_stream()` if frame is
+ * PUSH_PROMISE.
  *
  * The implementation of this function must return 0 if it succeeds.
- * It can return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` to
+ * It can return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` to
  * reset the stream (promised stream if frame is PUSH_PROMISE).  For
  * critical errors, it must return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other value is
- * returned, it is treated as if :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
- * is returned.  If :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+ * value is returned, it is treated as if
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned.  If
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
  * `nghttp2_session_mem_recv()` function will immediately return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_on_begin_headers_callback()`.
@@ -1675,16 +1697,17 @@ typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session,
  * The |value| of length |valuelen| is header value.  The |flags| is
  * bitwise OR of one or more of :type:`nghttp2_nv_flag`.
  *
- * If :enum:`NGHTTP2_NV_FLAG_NO_INDEX` is set in |flags|, the receiver
- * must not index this name/value pair when forwarding it to the next
- * hop.  More specifically, "Literal Header Field never Indexed"
- * representation must be used in HPACK encoding.
+ * If :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_INDEX` is set in
+ * |flags|, the receiver must not index this name/value pair when
+ * forwarding it to the next hop.  More specifically, "Literal Header
+ * Field never Indexed" representation must be used in HPACK encoding.
  *
  * When this callback is invoked, ``frame->hd.type`` is either
- * :enum:`NGHTTP2_HEADERS` or :enum:`NGHTTP2_PUSH_PROMISE`.  After all
- * header name/value pairs are processed with this callback, and no
- * error has been detected, :type:`nghttp2_on_frame_recv_callback`
- * will be invoked.  If there is an error in decompression,
+ * :enum:`nghttp2_frame_type.NGHTTP2_HEADERS` or
+ * :enum:`nghttp2_frame_type.NGHTTP2_PUSH_PROMISE`.  After all header
+ * name/value pairs are processed with this callback, and no error has
+ * been detected, :type:`nghttp2_on_frame_recv_callback` will be
+ * invoked.  If there is an error in decompression,
  * :type:`nghttp2_on_frame_recv_callback` for the |frame| will not be
  * invoked.
  *
@@ -1702,34 +1725,39 @@ typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session,
  * explained in :ref:`http-messaging` section.
  *
  * If the application uses `nghttp2_session_mem_recv()`, it can return
- * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
- * return without processing further input bytes.  The memory pointed
- * by |frame|, |name| and |value| parameters are retained until
- * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
- * The application must retain the input bytes which was used to
- * produce these parameters, because it may refer to the memory region
- * included in the input bytes.
- *
- * Returning :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close
- * the stream (promised stream if frame is PUSH_PROMISE) by issuing
- * RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`.  In this case,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
+ * `nghttp2_session_mem_recv()` return without processing further
+ * input bytes.  The memory pointed by |frame|, |name| and |value|
+ * parameters are retained until `nghttp2_session_mem_recv()` or
+ * `nghttp2_session_recv()` is called.  The application must retain
+ * the input bytes which was used to produce these parameters, because
+ * it may refer to the memory region included in the input bytes.
+ *
+ * Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+ * close the stream (promised stream if frame is PUSH_PROMISE) by
+ * issuing RST_STREAM with
+ * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`.  In this case,
  * :type:`nghttp2_on_header_callback` and
  * :type:`nghttp2_on_frame_recv_callback` will not be invoked.  If a
  * different error code is desirable, use
  * `nghttp2_submit_rst_stream()` with a desired error code and then
- * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  Again, use
- * ``frame->push_promise.promised_stream_id`` as stream_id parameter
- * in `nghttp2_submit_rst_stream()` if frame is PUSH_PROMISE.
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * Again, use ``frame->push_promise.promised_stream_id`` as stream_id
+ * parameter in `nghttp2_submit_rst_stream()` if frame is
+ * PUSH_PROMISE.
  *
  * The implementation of this function must return 0 if it succeeds.
- * It may return :enum:`NGHTTP2_ERR_PAUSE` or
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  For other critical
- * failures, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If
- * the other nonzero value is returned, it is treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
+ * It may return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` or
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  For
+ * other critical failures, it must return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+ * nonzero value is returned, it is treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
  * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_on_header_callback()`.
@@ -1796,11 +1824,12 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
  *
  * With this callback, application inspects the incoming invalid
  * field, and it also can reset stream from this callback by returning
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  By default, the
- * error code is :enum:`NGHTTP2_PROTOCOL_ERROR`.  To change the error
- * code, call `nghttp2_submit_rst_stream()` with the error code of
- * choice in addition to returning
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  By
+ * default, the error code is
+ * :enum:`nghttp2_error_code.NGHTTP2_PROTOCOL_ERROR`.  To change the
+ * error code, call `nghttp2_submit_rst_stream()` with the error code
+ * of choice in addition to returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
  *
  * If 0 is returned, the header field is ignored, and the stream is
  * not reset.
@@ -1831,11 +1860,12 @@ typedef int (*nghttp2_on_invalid_header_callback)(
  *
  * With this callback, application inspects the incoming invalid
  * field, and it also can reset stream from this callback by returning
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  By default, the
- * error code is :enum:`NGHTTP2_INTERNAL_ERROR`.  To change the error
- * code, call `nghttp2_submit_rst_stream()` with the error code of
- * choice in addition to returning
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  By
+ * default, the error code is
+ * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`.  To change the
+ * error code, call `nghttp2_submit_rst_stream()` with the error code
+ * of choice in addition to returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
  */
 typedef int (*nghttp2_on_invalid_header_callback2)(
     nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name,
@@ -1849,11 +1879,12 @@ typedef int (*nghttp2_on_invalid_header_callback2)(
  * |frame|.  The application must choose the total length of payload
  * including padded bytes in range [frame->hd.length, max_payloadlen],
  * inclusive.  Choosing number not in this range will be treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  Returning
  * ``frame->hd.length`` means no padding is added.  Returning
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will make
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will make
  * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_select_padding_callback()`.
@@ -1873,16 +1904,17 @@ typedef ssize_t (*nghttp2_select_padding_callback)(nghttp2_session *session,
  * |remote_max_frame_size|)].  If a value greater than this range is
  * returned than the max allow value will be used.  Returning a value
  * smaller than this range is treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  The |frame_type| is provided
- * for future extensibility and identifies the type of frame (see
- * :type:`nghttp2_frame_type`) for which to get the length for.
- * Currently supported frame types are: :enum:`NGHTTP2_DATA`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  The
+ * |frame_type| is provided for future extensibility and identifies
+ * the type of frame (see :type:`nghttp2_frame_type`) for which to get
+ * the length for.  Currently supported frame types are:
+ * :enum:`nghttp2_frame_type.NGHTTP2_DATA`.
  *
  * This callback can be used to control the length in bytes for which
  * :type:`nghttp2_data_source_read_callback` is allowed to send to the
  * remote endpoint.  This callback is optional.  Returning
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the entire session
- * failure.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will signal the
+ * entire session failure.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_data_source_read_length_callback()`.
@@ -1909,7 +1941,8 @@ typedef ssize_t (*nghttp2_data_source_read_length_callback)(
  * The implementation of this function must return 0 if it succeeds.
  * If nonzero value is returned, it is treated as fatal error and
  * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
  * `nghttp2_session_callbacks_set_on_begin_frame_callback()`.
@@ -1928,14 +1961,15 @@ typedef int (*nghttp2_on_begin_frame_callback)(nghttp2_session *session,
  * The implementation of this function must return 0 if it succeeds.
  *
  * To abort processing this extension frame, return
- * :enum:`NGHTTP2_ERR_CANCEL`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`.
  *
  * If fatal error occurred, application should return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
  * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the
- * other values are returned, currently they are treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+ * values are returned, currently they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  */
 typedef int (*nghttp2_on_extension_chunk_recv_callback)(
     nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data,
@@ -1965,14 +1999,15 @@ typedef int (*nghttp2_on_extension_chunk_recv_callback)(
  * |*payload|, and do its own mechanism to process extension frames.
  *
  * To abort processing this extension frame, return
- * :enum:`NGHTTP2_ERR_CANCEL`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`.
  *
  * If fatal error occurred, application should return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
  * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the
- * other values are returned, currently they are treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+ * values are returned, currently they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  */
 typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session,
                                                  void **payload,
@@ -1994,17 +2029,18 @@ typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session,
  * bytes written into |buf| when it succeeds.
  *
  * To abort processing this extension frame, return
- * :enum:`NGHTTP2_ERR_CANCEL`, and
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`, and
  * :type:`nghttp2_on_frame_not_send_callback` will be invoked.
  *
  * If fatal error occurred, application should return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
  * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the
- * other values are returned, currently they are treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the return value is
- * strictly larger than |len|, it is treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+ * values are returned, currently they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the return
+ * value is strictly larger than |len|, it is treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  */
 typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
                                                    uint8_t *buf, size_t len,
@@ -2029,12 +2065,12 @@ typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
  *
  * Normally, application should return 0 from this callback.  If fatal
  * error occurred while doing something in this callback, application
- * should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
- * library will return immediately with return value
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  Currently, if nonzero value
- * is returned from this callback, they are treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
- * rely on this details.
+ * should return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * In this case, library will return immediately with return value
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  Currently, if
+ * nonzero value is returned from this callback, they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, but application
+ * should not rely on this details.
  */
 typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg,
                                       size_t len, void *user_data);
@@ -2055,12 +2091,12 @@ typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg,
  *
  * Normally, application should return 0 from this callback.  If fatal
  * error occurred while doing something in this callback, application
- * should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
- * library will return immediately with return value
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  Currently, if nonzero value
- * is returned from this callback, they are treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
- * rely on this details.
+ * should return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * In this case, library will return immediately with return value
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  Currently, if
+ * nonzero value is returned from this callback, they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, but application
+ * should not rely on this details.
  */
 typedef int (*nghttp2_error_callback2)(nghttp2_session *session,
                                        int lib_error_code, const char *msg,
@@ -2090,7 +2126,7 @@ typedef struct nghttp2_session_callbacks nghttp2_session_callbacks;
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int
@@ -2287,7 +2323,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_frame_callback(
  * @function
  *
  * Sets callback function invoked when
- * :enum:`NGHTTP2_DATA_FLAG_NO_COPY` is used in
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in
  * :type:`nghttp2_data_source_read_callback` to avoid data copy.
  */
 NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_data_callback(
@@ -2470,7 +2506,7 @@ typedef struct nghttp2_option nghttp2_option;
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int nghttp2_option_new(nghttp2_option **option_ptr);
@@ -2531,7 +2567,8 @@ nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
  * If this option is not used or used with zero value, if MAGIC does
  * not match :macro:`NGHTTP2_CLIENT_MAGIC`, `nghttp2_session_recv()`
  * and `nghttp2_session_mem_recv()` will return error
- * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal error.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal
+ * error.
  */
 NGHTTP2_EXTERN void
 nghttp2_option_set_no_recv_client_magic(nghttp2_option *option, int val);
@@ -2616,8 +2653,8 @@ nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
  * received.  If this option is set to nonzero, the library won't send
  * PING frame with ACK flag set in the response for incoming PING
  * frame.  The application can send PING frame with ACK flag set using
- * `nghttp2_submit_ping()` with :enum:`NGHTTP2_FLAG_ACK` as flags
- * parameter.
+ * `nghttp2_submit_ping()` with :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK`
+ * as flags parameter.
  */
 NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option,
                                                         int val);
@@ -2631,7 +2668,7 @@ NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option,
  * `nghttp2_hd_deflate_bound()`.  The default value is 64KiB.  If
  * application attempts to send header fields larger than this limit,
  * the transmission of the frame fails with error code
- * :enum:`NGHTTP2_ERR_FRAME_SIZE_ERROR`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_FRAME_SIZE_ERROR`.
  */
 NGHTTP2_EXTERN void
 nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
@@ -2700,7 +2737,7 @@ NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int
@@ -2726,7 +2763,7 @@ nghttp2_session_client_new(nghttp2_session **session_ptr,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int
@@ -2752,7 +2789,7 @@ nghttp2_session_server_new(nghttp2_session **session_ptr,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int
@@ -2778,7 +2815,7 @@ nghttp2_session_client_new2(nghttp2_session **session_ptr,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int
@@ -2804,7 +2841,7 @@ nghttp2_session_server_new2(nghttp2_session **session_ptr,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int nghttp2_session_client_new3(
@@ -2829,7 +2866,7 @@ NGHTTP2_EXTERN int nghttp2_session_client_new3(
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int nghttp2_session_server_new3(
@@ -2851,12 +2888,14 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
  *
  * This function retrieves the highest prioritized frame from the
  * outbound queue and sends it to the remote peer.  It does this as
- * many as possible until the user callback
+ * many times as possible until the user callback
  * :type:`nghttp2_send_callback` returns
- * :enum:`NGHTTP2_ERR_WOULDBLOCK` or the outbound queue becomes empty.
- * This function calls several callback functions which are passed
- * when initializing the |session|.  Here is the simple time chart
- * which tells when each callback is invoked:
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`, the outbound queue
+ * becomes empty or flow control is triggered (remote window size
+ * becomes depleted or maximum number of concurrent streams is
+ * reached).  This function calls several callback functions which are
+ * passed when initializing the |session|.  Here is the simple time
+ * chart which tells when each callback is invoked:
  *
  * 1. Get the next frame to send from outbound queue.
  *
@@ -2874,7 +2913,7 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
  *
  * 6. :type:`nghttp2_before_frame_send_callback` is invoked.
  *
- * 7. If :enum:`NGHTTP2_ERR_CANCEL` is returned from
+ * 7. If :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL` is returned from
  *    :type:`nghttp2_before_frame_send_callback`, the current frame
  *    transmission is canceled, and
  *    :type:`nghttp2_on_frame_not_send_callback` is invoked.  Abort
@@ -2892,9 +2931,9 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
  *     The callback function failed.
  */
 NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
@@ -2926,7 +2965,7 @@ NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
  * |*data_ptr| if it succeeds, or one of the following negative error
  * codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  *
  * .. note::
@@ -2948,8 +2987,8 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
  *
  * This function receives as many frames as possible until the user
  * callback :type:`nghttp2_recv_callback` returns
- * :enum:`NGHTTP2_ERR_WOULDBLOCK`.  This function calls several
- * callback functions which are passed when initializing the
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`.  This function calls
+ * several callback functions which are passed when initializing the
  * |session|.  Here is the simple time chart which tells when each
  * callback is invoked:
  *
@@ -2994,18 +3033,18 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_EOF`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_EOF`
  *     The remote peer did shutdown on the connection.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
  *     The callback function failed.
- * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`
  *     Invalid client magic was detected.  This error only returns
  *     when |session| was configured as server and
  *     `nghttp2_option_set_no_recv_client_magic()` is not used with
  *     nonzero value.
- * :enum:`NGHTTP2_ERR_FLOODED`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED`
  *     Flooding was detected in this HTTP/2 session, and it must be
  *     closed.  This is most likely caused by misbehaviour of peer.
  */
@@ -3015,7 +3054,7 @@ NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session);
  * @function
  *
  * Processes data |in| as an input from the remote endpoint.  The
- * |inlen| indicates the number of bytes in the |in|.
+ * |inlen| indicates the number of bytes to receive in the |in|.
  *
  * This function behaves like `nghttp2_session_recv()` except that it
  * does not use :type:`nghttp2_recv_callback` to receive data; the
@@ -3024,27 +3063,27 @@ NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session);
  * are called in the same way as they are in `nghttp2_session_recv()`.
  *
  * In the current implementation, this function always tries to
- * processes all input data unless either an error occurs or
- * :enum:`NGHTTP2_ERR_PAUSE` is returned from
+ * processes |inlen| bytes of input data unless either an error occurs or
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is returned from
  * :type:`nghttp2_on_header_callback` or
  * :type:`nghttp2_on_data_chunk_recv_callback`.  If
- * :enum:`NGHTTP2_ERR_PAUSE` is used, the return value includes the
- * number of bytes which was used to produce the data or frame for the
- * callback.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is used, the return value
+ * includes the number of bytes which was used to produce the data or
+ * frame for the callback.
  *
  * This function returns the number of processed bytes, or one of the
  * following negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
  *     The callback function failed.
- * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`
  *     Invalid client magic was detected.  This error only returns
  *     when |session| was configured as server and
  *     `nghttp2_option_set_no_recv_client_magic()` is not used with
  *     nonzero value.
- * :enum:`NGHTTP2_ERR_FLOODED`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED`
  *     Flooding was detected in this HTTP/2 session, and it must be
  *     closed.  This is most likely caused by misbehaviour of peer.
  */
@@ -3061,9 +3100,9 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The stream does not exist; or no deferred data exist.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int nghttp2_session_resume_data(nghttp2_session *session,
@@ -3124,7 +3163,7 @@ nghttp2_session_get_stream_user_data(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The stream does not exist
  */
 NGHTTP2_EXTERN int
@@ -3341,7 +3380,7 @@ nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session);
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int nghttp2_session_terminate_session(nghttp2_session *session,
@@ -3368,9 +3407,9 @@ NGHTTP2_EXTERN int nghttp2_session_terminate_session(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |last_stream_id| is invalid.
  */
 NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session,
@@ -3385,7 +3424,7 @@ NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session,
  *
  * This function is only usable for server.  If this function is
  * called with client side session, this function returns
- * :enum:`NGHTTP2_ERR_INVALID_STATE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`.
  *
  * To gracefully shutdown HTTP/2 session, server should call this
  * function to send GOAWAY with last_stream_id (1u << 31) - 1.  And
@@ -3407,9 +3446,9 @@ NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
  *     The |session| is initialized as client.
  */
 NGHTTP2_EXTERN int nghttp2_submit_shutdown_notice(nghttp2_session *session);
@@ -3444,7 +3483,7 @@ NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings(
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |next_stream_id| is strictly less than the value
  *     `nghttp2_session_get_next_stream_id()` returns; or
  *     |next_stream_id| is invalid (e.g., even integer for client, or
@@ -3479,11 +3518,11 @@ nghttp2_session_get_next_stream_id(nghttp2_session *session);
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |stream_id| is 0.
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
  *     Automatic WINDOW_UPDATE is not disabled.
  */
 NGHTTP2_EXTERN int nghttp2_session_consume(nghttp2_session *session,
@@ -3500,9 +3539,9 @@ NGHTTP2_EXTERN int nghttp2_session_consume(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
  *     Automatic WINDOW_UPDATE is not disabled.
  */
 NGHTTP2_EXTERN int nghttp2_session_consume_connection(nghttp2_session *session,
@@ -3519,11 +3558,11 @@ NGHTTP2_EXTERN int nghttp2_session_consume_connection(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |stream_id| is 0.
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
  *     Automatic WINDOW_UPDATE is not disabled.
  */
 NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
@@ -3553,9 +3592,9 @@ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     Attempted to depend on itself; or no stream exist for the given
  *     |stream_id|; or |stream_id| is 0
  */
@@ -3596,9 +3635,9 @@ nghttp2_session_change_stream_priority(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     Attempted to depend on itself; or stream denoted by |stream_id|
  *     already exists; or |stream_id| cannot be used to create idle
  *     stream (in other words, local endpoint has already opened
@@ -3649,11 +3688,11 @@ nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |settings_payload| is badly formed.
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
  *     The stream ID 1 is already used or closed; or is not available.
  */
 NGHTTP2_EXTERN int nghttp2_session_upgrade(nghttp2_session *session,
@@ -3693,11 +3732,11 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |settings_payload| is badly formed.
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
  *     The stream ID 1 is already used or closed; or is not available.
  */
 NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session,
@@ -3721,10 +3760,10 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session,
  * This function returns the number of bytes written in |buf|, or one
  * of the following negative error codes:
  *
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |iv| contains duplicate settings ID or invalid value.
  *
- * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
  *     The provided |buflen| size is too small to hold the output.
  */
 NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload(
@@ -3755,8 +3794,8 @@ NGHTTP2_EXTERN const char *nghttp2_http2_strerror(uint32_t error_code);
  * on with |weight| and its exclusive flag.  If |exclusive| is
  * nonzero, exclusive flag is set.
  *
- * The |weight| must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
- * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive.
+ * The |weight| must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
+ * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.
  */
 NGHTTP2_EXTERN void nghttp2_priority_spec_init(nghttp2_priority_spec *pri_spec,
                                                int32_t stream_id,
@@ -3791,11 +3830,12 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
  * use `nghttp2_priority_spec_init()`.  If |pri_spec| is not ``NULL``,
  * this function will copy its data members.
  *
- * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
- * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight`` is
- * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
- * :enum:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
- * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
+ * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight``
+ * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
+ * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MAX_WEIGHT`.
  *
  * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
  * |nvlen| elements.  The application is responsible to include
@@ -3806,12 +3846,12 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
  * This function creates copies of all name/value pairs in |nva|.  It
  * also lower-cases all names in |nva|.  The order of elements in
  * |nva| is preserved.  For header fields with
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
- * and value are not copied respectively.  With
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
- * pass header field name in lowercase.  The application should
- * maintain the references to them until
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively.  With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase.  The
+ * application should maintain the references to them until
  * :type:`nghttp2_on_frame_send_callback` or
  * :type:`nghttp2_on_frame_not_send_callback` is called.
  *
@@ -3833,15 +3873,15 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
  * This function returns assigned stream ID if it succeeds, or one of
  * the following negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
  *     No stream ID is available because maximum stream ID was
  *     reached.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     Trying to depend on itself (new stream ID equals
  *     ``pri_spec->stream_id``).
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
  *     The |session| is server session.
  *
  * .. warning::
@@ -3876,12 +3916,12 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request(
  * This function creates copies of all name/value pairs in |nva|.  It
  * also lower-cases all names in |nva|.  The order of elements in
  * |nva| is preserved.  For header fields with
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
- * and value are not copied respectively.  With
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
- * pass header field name in lowercase.  The application should
- * maintain the references to them until
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively.  With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase.  The
+ * application should maintain the references to them until
  * :type:`nghttp2_on_frame_send_callback` or
  * :type:`nghttp2_on_frame_not_send_callback` is called.
  *
@@ -3907,16 +3947,16 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request(
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |stream_id| is 0.
- * :enum:`NGHTTP2_ERR_DATA_EXIST`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
  *     DATA or HEADERS has been already submitted and not fully
  *     processed yet.  Normally, this does not happen, but when
  *     application wrongly calls `nghttp2_submit_response()` twice,
  *     this may happen.
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
  *     The |session| is client session.
  *
  * .. warning::
@@ -3942,12 +3982,12 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
  * This function creates copies of all name/value pairs in |nva|.  It
  * also lower-cases all names in |nva|.  The order of elements in
  * |nva| is preserved.  For header fields with
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
- * and value are not copied respectively.  With
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
- * pass header field name in lowercase.  The application should
- * maintain the references to them until
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively.  With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase.  The
+ * application should maintain the references to them until
  * :type:`nghttp2_on_frame_send_callback` or
  * :type:`nghttp2_on_frame_not_send_callback` is called.
  *
@@ -3959,16 +3999,16 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
  * |nva| will be sent as response headers, which will result in error.
  *
  * This function has the same effect with `nghttp2_submit_headers()`,
- * with flags = :enum:`NGHTTP2_FLAG_END_STREAM` and both pri_spec and
- * stream_user_data to NULL.
+ * with flags = :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` and both
+ * pri_spec and stream_user_data to NULL.
  *
  * To submit trailer fields after `nghttp2_submit_response()` is
  * called, the application has to specify
  * :type:`nghttp2_data_provider` to `nghttp2_submit_response()`.
  * Inside of :type:`nghttp2_data_source_read_callback`, when setting
- * :enum:`NGHTTP2_DATA_FLAG_EOF`, also set
- * :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM`.  After that, the
- * application can send trailer fields using
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF`, also set
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM`.  After
+ * that, the application can send trailer fields using
  * `nghttp2_submit_trailer()`.  `nghttp2_submit_trailer()` can be used
  * inside :type:`nghttp2_data_source_read_callback`.
  *
@@ -3976,9 +4016,9 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
  * Otherwise, this function returns 0 if it succeeds, or one of the
  * following negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |stream_id| is 0.
  */
 NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
@@ -3991,10 +4031,10 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
  * Submits HEADERS frame. The |flags| is bitwise OR of the
  * following values:
  *
- * * :enum:`NGHTTP2_FLAG_END_STREAM`
+ * * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`
  *
- * If |flags| includes :enum:`NGHTTP2_FLAG_END_STREAM`, this frame has
- * END_STREAM flag set.
+ * If |flags| includes :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`,
+ * this frame has END_STREAM flag set.
  *
  * The library handles the CONTINUATION frame internally and it
  * correctly sets END_HEADERS to the last sequence of the PUSH_PROMISE
@@ -4011,11 +4051,11 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
  * use `nghttp2_priority_spec_init()`.  If |pri_spec| is not ``NULL``,
  * this function will copy its data members.
  *
- * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
- * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight`` is
- * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
- * :enum:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
- * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
+ * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight``
+ * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
+ * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`.
  *
  * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
  * |nvlen| elements.  The application is responsible to include
@@ -4026,12 +4066,12 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
  * This function creates copies of all name/value pairs in |nva|.  It
  * also lower-cases all names in |nva|.  The order of elements in
  * |nva| is preserved.  For header fields with
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
- * and value are not copied respectively.  With
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
- * pass header field name in lowercase.  The application should
- * maintain the references to them until
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively.  With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase.  The
+ * application should maintain the references to them until
  * :type:`nghttp2_on_frame_send_callback` or
  * :type:`nghttp2_on_frame_not_send_callback` is called.
  *
@@ -4049,19 +4089,19 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
  * |stream_id| is -1.  Otherwise, this function returns 0 if it
  * succeeds, or one of the following negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
  *     No stream ID is available because maximum stream ID was
  *     reached.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |stream_id| is 0; or trying to depend on itself (stream ID
  *     equals ``pri_spec->stream_id``).
- * :enum:`NGHTTP2_ERR_DATA_EXIST`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
  *     DATA or HEADERS has been already submitted and not fully
  *     processed yet.  This happens if stream denoted by |stream_id|
  *     is in reserved state.
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
  *     The |stream_id| is -1, and |session| is server session.
  *
  * .. warning::
@@ -4083,8 +4123,8 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_headers(
  *
  * Submits one or more DATA frames to the stream |stream_id|.  The
  * data to be sent are provided by |data_prd|.  If |flags| contains
- * :enum:`NGHTTP2_FLAG_END_STREAM`, the last DATA frame has END_STREAM
- * flag set.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, the last DATA frame
+ * has END_STREAM flag set.
  *
  * This function does not take ownership of the |data_prd|.  The
  * function copies the members of the |data_prd|.
@@ -4092,27 +4132,28 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_headers(
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_DATA_EXIST`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
  *     DATA or HEADERS has been already submitted and not fully
  *     processed yet.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |stream_id| is 0.
- * :enum:`NGHTTP2_ERR_STREAM_CLOSED`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED`
  *     The stream was already closed; or the |stream_id| is invalid.
  *
  * .. note::
  *
  *   Currently, only one DATA or HEADERS is allowed for a stream at a
  *   time.  Submitting these frames more than once before first DATA
- *   or HEADERS is finished results in :enum:`NGHTTP2_ERR_DATA_EXIST`
- *   error code.  The earliest callback which tells that previous
- *   frame is done is :type:`nghttp2_on_frame_send_callback`.  In side
- *   that callback, new data can be submitted using
- *   `nghttp2_submit_data()`.  Of course, all data except for last one
- *   must not have :enum:`NGHTTP2_FLAG_END_STREAM` flag set in
- *   |flags|.  This sounds a bit complicated, and we recommend to use
+ *   or HEADERS is finished results in
+ *   :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` error code.  The
+ *   earliest callback which tells that previous frame is done is
+ *   :type:`nghttp2_on_frame_send_callback`.  In side that callback,
+ *   new data can be submitted using `nghttp2_submit_data()`.  Of
+ *   course, all data except for last one must not have
+ *   :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` flag set in |flags|.
+ *   This sounds a bit complicated, and we recommend to use
  *   `nghttp2_submit_request()` and `nghttp2_submit_response()` to
  *   avoid this cascading issue.  The experience shows that for HTTP
  *   use, these two functions are enough to implement both client and
@@ -4129,25 +4170,26 @@ NGHTTP2_EXTERN int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
  * to the priority specification |pri_spec|.
  *
  * The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
  *
  * The |pri_spec| is priority specification of this request.  ``NULL``
  * is not allowed for this function. To specify the priority, use
  * `nghttp2_priority_spec_init()`.  This function will copy its data
  * members.
  *
- * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
- * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight`` is
- * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
- * :enum:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
- * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
+ * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight``
+ * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
+ * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MAX_WEIGHT`.
  *
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |stream_id| is 0; or the |pri_spec| is NULL; or trying to
  *     depend on itself.
  */
@@ -4165,14 +4207,14 @@ nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
  * The pre-defined error code is one of :enum:`nghttp2_error_code`.
  *
  * The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
  *
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |stream_id| is 0.
  */
 NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session,
@@ -4187,7 +4229,7 @@ NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session,
  * indicates the number of :type:`nghttp2_settings_entry`.
  *
  * The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
  *
  * This function does not take ownership of the |iv|.  This function
  * copies all the elements in the |iv|.
@@ -4196,16 +4238,17 @@ NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session,
  * size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE,
  * RST_STREAM is issued against such a stream.
  *
- * SETTINGS with :enum:`NGHTTP2_FLAG_ACK` is automatically submitted
- * by the library and application could not send it at its will.
+ * SETTINGS with :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK` is
+ * automatically submitted by the library and application could not
+ * send it at its will.
  *
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |iv| contains invalid value (e.g., initial window size
  *     strictly greater than (1 << 31) - 1.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
@@ -4233,12 +4276,12 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
  * This function creates copies of all name/value pairs in |nva|.  It
  * also lower-cases all names in |nva|.  The order of elements in
  * |nva| is preserved.  For header fields with
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
- * and value are not copied respectively.  With
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
- * pass header field name in lowercase.  The application should
- * maintain the references to them until
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively.  With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase.  The
+ * application should maintain the references to them until
  * :type:`nghttp2_on_frame_send_callback` or
  * :type:`nghttp2_on_frame_not_send_callback` is called.
  *
@@ -4257,18 +4300,18 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
  * This function returns assigned promised stream ID if it succeeds,
  * or one of the following negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
  *     This function was invoked when |session| is initialized as
  *     client.
- * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
  *     No stream ID is available because maximum stream ID was
  *     reached.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |stream_id| is 0; The |stream_id| does not designate stream
  *     that peer initiated.
- * :enum:`NGHTTP2_ERR_STREAM_CLOSED`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED`
  *     The stream was already closed; or the |stream_id| is invalid.
  *
  * .. warning::
@@ -4297,10 +4340,10 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise(
  *
  * The |flags| is bitwise OR of 0 or more of the following value.
  *
- * * :enum:`NGHTTP2_FLAG_ACK`
+ * * :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK`
  *
  * Unless `nghttp2_option_set_no_auto_ping_ack()` is used, the |flags|
- * should be :enum:`NGHTTP2_FLAG_NONE`.
+ * should be :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
  *
  * If the |opaque_data| is non ``NULL``, then it should point to the 8
  * bytes array of memory to specify opaque data to send with PING
@@ -4310,7 +4353,7 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise(
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
@@ -4325,7 +4368,7 @@ NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
  * The pre-defined error code is one of :enum:`nghttp2_error_code`.
  *
  * The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
  *
  * The |last_stream_id| is peer's stream ID or 0.  So if |session| is
  * initialized as client, |last_stream_id| must be even or 0.  If
@@ -4355,9 +4398,9 @@ NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |opaque_data_len| is too large; the |last_stream_id| is
  *     invalid.
  */
@@ -4413,7 +4456,7 @@ nghttp2_session_check_server_session(nghttp2_session *session);
  * Submits WINDOW_UPDATE frame.
  *
  * The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
  *
  * The |stream_id| is the stream ID to send this WINDOW_UPDATE.  To
  * send connection level WINDOW_UPDATE, specify 0 to |stream_id|.
@@ -4440,9 +4483,9 @@ nghttp2_session_check_server_session(nghttp2_session *session);
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_FLOW_CONTROL`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_FLOW_CONTROL`
  *     The local window size overflow or gets negative.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session,
@@ -4460,7 +4503,7 @@ NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session,
  * to transmission queue.
  *
  * The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
  *
  * This sounds similar to `nghttp2_submit_window_update()`, but there
  * are 2 differences.  The first difference is that this function
@@ -4479,9 +4522,9 @@ NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session,
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The |stream_id| is negative.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int
@@ -4512,18 +4555,19 @@ nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags,
  *
  * The standard HTTP/2 frame cannot be sent with this function, so
  * |type| must be strictly grater than 0x9.  Otherwise, this function
- * will fail with error code :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`.
+ * will fail with error code
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`.
  *
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
  *     If :type:`nghttp2_pack_extension_callback` is not set.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     If  |type| specifies  standard  HTTP/2 frame  type.  The  frame
  *     types  in the  rage [0x0,  0x9], both  inclusive, are  standard
  *     HTTP/2 frame type, and cannot be sent using this function.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory
  */
 NGHTTP2_EXTERN int nghttp2_submit_extension(nghttp2_session *session,
@@ -4537,8 +4581,8 @@ NGHTTP2_EXTERN int nghttp2_submit_extension(nghttp2_session *session,
  * extension to HTTP/2.  If this frame is received, and
  * `nghttp2_option_set_user_recv_extension_type()` is not set, and
  * `nghttp2_option_set_builtin_recv_extension_type()` is set for
- * :enum:`NGHTTP2_ALTSVC`, ``nghttp2_extension.payload`` will point to
- * this struct.
+ * :enum:`nghttp2_frame_type.NGHTTP2_ALTSVC`,
+ * ``nghttp2_extension.payload`` will point to this struct.
  *
  * It has the following members:
  */
@@ -4572,7 +4616,7 @@ typedef struct {
  * `RFC 7383 <https://tools.ietf.org/html/rfc7838#section-4>`_.
  *
  * The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
  *
  * The |origin| points to the origin this alternative service is
  * associated with.  The |origin_len| is the length of the origin.  If
@@ -4582,16 +4626,16 @@ typedef struct {
  *
  * The ALTSVC frame is only usable from server side.  If this function
  * is invoked with client side session, this function returns
- * :enum:`NGHTTP2_ERR_INVALID_STATE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`.
  *
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
  *     The function is called from client side session
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     The sum of |origin_len| and |field_value_len| is larger than
  *     16382; or |origin_len| is 0 while |stream_id| is 0; or
  *     |origin_len| is not 0 while |stream_id| is not 0.
@@ -4630,8 +4674,8 @@ typedef struct {
  * If this frame is received, and
  * `nghttp2_option_set_user_recv_extension_type()` is not set, and
  * `nghttp2_option_set_builtin_recv_extension_type()` is set for
- * :enum:`NGHTTP2_ORIGIN`, ``nghttp2_extension.payload`` will point to
- * this struct.
+ * :enum:`nghttp2_frame_type.NGHTTP2_ORIGIN`,
+ * ``nghttp2_extension.payload`` will point to this struct.
  *
  * It has the following members:
  */
@@ -4655,7 +4699,7 @@ typedef struct {
  * `RFC 8336 <https://tools.ietf.org/html/rfc8336>`_.
  *
  * The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
  *
  * The |ov| points to the array of origins.  The |nov| specifies the
  * number of origins included in |ov|.  This function creates copies
@@ -4663,13 +4707,13 @@ typedef struct {
  *
  * The ORIGIN frame is only usable by a server.  If this function is
  * invoked with client side session, this function returns
- * :enum:`NGHTTP2_ERR_INVALID_STATE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`.
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
  *     The function is called from client side session.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     There are too many origins, or an origin is too large to fit
  *     into a default frame payload.
  */
@@ -4795,7 +4839,31 @@ NGHTTP2_EXTERN int nghttp2_check_header_value(const uint8_t *value, size_t len);
 /**
  * @function
  *
- * Returns nonzero if the |value| which is supposed to the value of
+ * Returns nonzero if the |value| which is supposed to be the value of
+ * the :method header field is valid according to
+ * https://datatracker.ietf.org/doc/html/rfc7231#section-4 and
+ * https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
+ */
+NGHTTP2_EXTERN int nghttp2_check_method(const uint8_t *value, size_t len);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the |value| which is supposed to be the value of
+ * the :path header field is valid according to
+ * https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.3
+ *
+ * |value| is valid if it merely consists of the allowed characters.
+ * In particular, it does not check whether |value| follows the syntax
+ * of path.  The allowed characters are all characters valid by
+ * `nghttp2_check_header_value` minus SPC and HT.
+ */
+NGHTTP2_EXTERN int nghttp2_check_path(const uint8_t *value, size_t len);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the |value| which is supposed to be the value of the
  * :authority or host header field is valid according to
  * https://tools.ietf.org/html/rfc3986#section-3.2
  *
@@ -4829,7 +4897,7 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int
@@ -4883,7 +4951,7 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int
@@ -4897,24 +4965,24 @@ nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
  * the |buf| of length |buflen|.
  *
  * If |buf| is not large enough to store the deflated header block,
- * this function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`.  The
- * caller should use `nghttp2_hd_deflate_bound()` to know the upper
- * bound of buffer size required to deflate given header name/value
- * pairs.
+ * this function fails with
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`.  The caller
+ * should use `nghttp2_hd_deflate_bound()` to know the upper bound of
+ * buffer size required to deflate given header name/value pairs.
  *
  * Once this function fails, subsequent call of this function always
- * returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
+ * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`.
  *
  * After this function returns, it is safe to delete the |nva|.
  *
  * This function returns the number of bytes written to |buf| if it
  * succeeds, or one of the following negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
  *     Deflation process has failed.
- * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
  *     The provided |buflen| size is too small to hold the output.
  */
 NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
@@ -4930,23 +4998,24 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
  * must be set in len field of :type:`nghttp2_vec`.  If and only if
  * one chunk is filled up completely, next chunk will be used.  If
  * |vec| is not large enough to store the deflated header block, this
- * function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`.  The caller
+ * function fails with
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`.  The caller
  * should use `nghttp2_hd_deflate_bound()` to know the upper bound of
  * buffer size required to deflate given header name/value pairs.
  *
  * Once this function fails, subsequent call of this function always
- * returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
+ * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`.
  *
  * After this function returns, it is safe to delete the |nva|.
  *
  * This function returns the number of bytes written to |vec| if it
  * succeeds, or one of the following negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
  *     Deflation process has failed.
- * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
  *     The provided |buflen| size is too small to hold the output.
  */
 NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
@@ -5026,7 +5095,7 @@ typedef struct nghttp2_hd_inflater nghttp2_hd_inflater;
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
  */
 NGHTTP2_EXTERN int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
@@ -5075,9 +5144,9 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
  *     The function is called while header block is being inflated.
  *     Probably, application missed to call
  *     `nghttp2_hd_inflate_end_headers()`.
@@ -5115,7 +5184,8 @@ typedef enum {
  *
  * Inflates name/value block stored in |in| with length |inlen|.  This
  * function performs decompression.  For each successful emission of
- * header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in
+ * header name/value pair,
+ * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in
  * |*inflate_flags| and name/value pair is assigned to the |nv_out|
  * and the function returns.  The caller must not free the members of
  * |nv_out|.
@@ -5138,11 +5208,11 @@ typedef enum {
  * This function returns the number of bytes processed if it succeeds,
  * or one of the following negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
  *     Inflation process has failed.
- * :enum:`NGHTTP2_ERR_BUFFER_ERROR`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR`
  *     The header field name or value is too large.
  *
  * Example follows::
@@ -5197,7 +5267,8 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
  *
  * Inflates name/value block stored in |in| with length |inlen|.  This
  * function performs decompression.  For each successful emission of
- * header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in
+ * header name/value pair,
+ * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in
  * |*inflate_flags| and name/value pair is assigned to the |nv_out|
  * and the function returns.  The caller must not free the members of
  * |nv_out|.
@@ -5213,8 +5284,9 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
  * for the next header block input.
  *
  * In other words, if |in_final| is nonzero, and this function returns
- * |inlen|, you can assert that :enum:`NGHTTP2_HD_INFLATE_FINAL` is
- * set in |*inflate_flags|.
+ * |inlen|, you can assert that
+ * :enum:`nghttp2_hd_inflate_final.NGHTTP2_HD_INFLATE_FINAL` is set in
+ * |*inflate_flags|.
  *
  * The caller can feed complete compressed header block.  It also can
  * feed it in several chunks.  The caller must set |in_final| to
@@ -5224,11 +5296,11 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
  * This function returns the number of bytes processed if it succeeds,
  * or one of the following negative error codes:
  *
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
- * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
  *     Inflation process has failed.
- * :enum:`NGHTTP2_ERR_BUFFER_ERROR`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR`
  *     The header field name or value is too large.
  *
  * Example follows::
@@ -5399,7 +5471,7 @@ typedef enum {
  *
  * Returns state of |stream|.  The root stream retrieved by
  * `nghttp2_session_get_root_stream()` will have stream state
- * :enum:`NGHTTP2_STREAM_STATE_IDLE`.
+ * :enum:`nghttp2_stream_proto_state.NGHTTP2_STREAM_STATE_IDLE`.
  */
 NGHTTP2_EXTERN nghttp2_stream_proto_state
 nghttp2_stream_get_state(nghttp2_stream *stream);
index 795a44c..0b909b4 100644 (file)
@@ -29,7 +29,7 @@
  * @macro
  * Version number of the nghttp2 library release
  */
-#define NGHTTP2_VERSION "1.41.0"
+#define NGHTTP2_VERSION "1.46.0"
 
 /**
  * @macro
@@ -37,6 +37,6 @@
  * release. This is a 24 bit number with 8 bits for major number, 8 bits
  * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
  */
-#define NGHTTP2_VERSION_NUM 0x012900
+#define NGHTTP2_VERSION_NUM 0x012e00
 
 #endif /* NGHTTP2VER_H */
index 2a435be..a328447 100644 (file)
@@ -82,8 +82,10 @@ void nghttp2_buf_reset(nghttp2_buf *buf) {
 }
 
 void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len) {
-  buf->begin = buf->pos = buf->last = buf->mark = begin;
-  buf->end = begin + len;
+  buf->begin = buf->pos = buf->last = buf->mark = buf->end = begin;
+  if (len) {
+    buf->end += len;
+  }
 }
 
 static int buf_chain_new(nghttp2_buf_chain **chain, size_t chunk_length,
index 4821de4..382a26c 100644 (file)
@@ -818,8 +818,10 @@ int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
   size_t len = 0;
 
   origin = frame->payload;
-  p = payload;
-  end = p + payloadlen;
+  p = end = payload;
+  if (payloadlen) {
+    end += payloadlen;
+  }
 
   for (; p != end;) {
     if (end - p < 2) {
@@ -897,9 +899,25 @@ nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
 }
 
 int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b) {
-  return a->namelen == b->namelen && a->valuelen == b->valuelen &&
-         memcmp(a->name, b->name, a->namelen) == 0 &&
-         memcmp(a->value, b->value, a->valuelen) == 0;
+  if (a->namelen != b->namelen || a->valuelen != b->valuelen) {
+    return 0;
+  }
+
+  if (a->name == NULL || b->name == NULL) {
+    assert(a->namelen == 0);
+    assert(b->namelen == 0);
+  } else if (memcmp(a->name, b->name, a->namelen) != 0) {
+    return 0;
+  }
+
+  if (a->value == NULL || b->value == NULL) {
+    assert(a->valuelen == 0);
+    assert(b->valuelen == 0);
+  } else if (memcmp(a->value, b->value, a->valuelen) != 0) {
+    return 0;
+  }
+
+  return 1;
 }
 
 void nghttp2_nv_array_del(nghttp2_nv *nva, nghttp2_mem *mem) {
index 615bbf3..4b9222a 100644 (file)
@@ -57,7 +57,7 @@
 
 /* Maximum headers block size to send, calculated using
    nghttp2_hd_deflate_bound().  This is the default value, and can be
-   overridden by nghttp2_option_set_max_send_header_block_size(). */
+   overridden by nghttp2_option_set_max_send_header_block_length(). */
 #define NGHTTP2_MAX_HEADERSLEN 65536
 
 /* The number of bytes for each SETTINGS entry */
index 0bd5414..588e269 100644 (file)
@@ -507,7 +507,166 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len) {
   return 1;
 }
 
-/* Generated by genauthroitychartbl.py */
+/* Generated by genmethodchartbl.py */
+static char VALID_METHOD_CHARS[] = {
+    0 /* NUL  */, 0 /* SOH  */, 0 /* STX  */, 0 /* ETX  */,
+    0 /* EOT  */, 0 /* ENQ  */, 0 /* ACK  */, 0 /* BEL  */,
+    0 /* BS   */, 0 /* HT   */, 0 /* LF   */, 0 /* VT   */,
+    0 /* FF   */, 0 /* CR   */, 0 /* SO   */, 0 /* SI   */,
+    0 /* DLE  */, 0 /* DC1  */, 0 /* DC2  */, 0 /* DC3  */,
+    0 /* DC4  */, 0 /* NAK  */, 0 /* SYN  */, 0 /* ETB  */,
+    0 /* CAN  */, 0 /* EM   */, 0 /* SUB  */, 0 /* ESC  */,
+    0 /* FS   */, 0 /* GS   */, 0 /* RS   */, 0 /* US   */,
+    0 /* SPC  */, 1 /* !    */, 0 /* "    */, 1 /* #    */,
+    1 /* $    */, 1 /* %    */, 1 /* &    */, 1 /* '    */,
+    0 /* (    */, 0 /* )    */, 1 /* *    */, 1 /* +    */,
+    0 /* ,    */, 1 /* -    */, 1 /* .    */, 0 /* /    */,
+    1 /* 0    */, 1 /* 1    */, 1 /* 2    */, 1 /* 3    */,
+    1 /* 4    */, 1 /* 5    */, 1 /* 6    */, 1 /* 7    */,
+    1 /* 8    */, 1 /* 9    */, 0 /* :    */, 0 /* ;    */,
+    0 /* <    */, 0 /* =    */, 0 /* >    */, 0 /* ?    */,
+    0 /* @    */, 1 /* A    */, 1 /* B    */, 1 /* C    */,
+    1 /* D    */, 1 /* E    */, 1 /* F    */, 1 /* G    */,
+    1 /* H    */, 1 /* I    */, 1 /* J    */, 1 /* K    */,
+    1 /* L    */, 1 /* M    */, 1 /* N    */, 1 /* O    */,
+    1 /* P    */, 1 /* Q    */, 1 /* R    */, 1 /* S    */,
+    1 /* T    */, 1 /* U    */, 1 /* V    */, 1 /* W    */,
+    1 /* X    */, 1 /* Y    */, 1 /* Z    */, 0 /* [    */,
+    0 /* \    */, 0 /* ]    */, 1 /* ^    */, 1 /* _    */,
+    1 /* `    */, 1 /* a    */, 1 /* b    */, 1 /* c    */,
+    1 /* d    */, 1 /* e    */, 1 /* f    */, 1 /* g    */,
+    1 /* h    */, 1 /* i    */, 1 /* j    */, 1 /* k    */,
+    1 /* l    */, 1 /* m    */, 1 /* n    */, 1 /* o    */,
+    1 /* p    */, 1 /* q    */, 1 /* r    */, 1 /* s    */,
+    1 /* t    */, 1 /* u    */, 1 /* v    */, 1 /* w    */,
+    1 /* x    */, 1 /* y    */, 1 /* z    */, 0 /* {    */,
+    1 /* |    */, 0 /* }    */, 1 /* ~    */, 0 /* DEL  */,
+    0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
+    0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
+    0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
+    0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
+    0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
+    0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
+    0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
+    0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
+    0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
+    0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
+    0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
+    0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
+    0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
+    0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
+    0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
+    0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
+    0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
+    0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
+    0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
+    0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
+    0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
+    0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
+    0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
+    0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
+    0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
+    0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
+    0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
+    0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
+    0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
+    0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
+    0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
+    0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
+};
+
+int nghttp2_check_method(const uint8_t *value, size_t len) {
+  const uint8_t *last;
+  if (len == 0) {
+    return 0;
+  }
+  for (last = value + len; value != last; ++value) {
+    if (!VALID_METHOD_CHARS[*value]) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/* Generated by genpathchartbl.py */
+static char VALID_PATH_CHARS[] = {
+    0 /* NUL  */, 0 /* SOH  */, 0 /* STX  */, 0 /* ETX  */,
+    0 /* EOT  */, 0 /* ENQ  */, 0 /* ACK  */, 0 /* BEL  */,
+    0 /* BS   */, 0 /* HT   */, 0 /* LF   */, 0 /* VT   */,
+    0 /* FF   */, 0 /* CR   */, 0 /* SO   */, 0 /* SI   */,
+    0 /* DLE  */, 0 /* DC1  */, 0 /* DC2  */, 0 /* DC3  */,
+    0 /* DC4  */, 0 /* NAK  */, 0 /* SYN  */, 0 /* ETB  */,
+    0 /* CAN  */, 0 /* EM   */, 0 /* SUB  */, 0 /* ESC  */,
+    0 /* FS   */, 0 /* GS   */, 0 /* RS   */, 0 /* US   */,
+    0 /* SPC  */, 1 /* !    */, 1 /* "    */, 1 /* #    */,
+    1 /* $    */, 1 /* %    */, 1 /* &    */, 1 /* '    */,
+    1 /* (    */, 1 /* )    */, 1 /* *    */, 1 /* +    */,
+    1 /* ,    */, 1 /* -    */, 1 /* .    */, 1 /* /    */,
+    1 /* 0    */, 1 /* 1    */, 1 /* 2    */, 1 /* 3    */,
+    1 /* 4    */, 1 /* 5    */, 1 /* 6    */, 1 /* 7    */,
+    1 /* 8    */, 1 /* 9    */, 1 /* :    */, 1 /* ;    */,
+    1 /* <    */, 1 /* =    */, 1 /* >    */, 1 /* ?    */,
+    1 /* @    */, 1 /* A    */, 1 /* B    */, 1 /* C    */,
+    1 /* D    */, 1 /* E    */, 1 /* F    */, 1 /* G    */,
+    1 /* H    */, 1 /* I    */, 1 /* J    */, 1 /* K    */,
+    1 /* L    */, 1 /* M    */, 1 /* N    */, 1 /* O    */,
+    1 /* P    */, 1 /* Q    */, 1 /* R    */, 1 /* S    */,
+    1 /* T    */, 1 /* U    */, 1 /* V    */, 1 /* W    */,
+    1 /* X    */, 1 /* Y    */, 1 /* Z    */, 1 /* [    */,
+    1 /* \    */, 1 /* ]    */, 1 /* ^    */, 1 /* _    */,
+    1 /* `    */, 1 /* a    */, 1 /* b    */, 1 /* c    */,
+    1 /* d    */, 1 /* e    */, 1 /* f    */, 1 /* g    */,
+    1 /* h    */, 1 /* i    */, 1 /* j    */, 1 /* k    */,
+    1 /* l    */, 1 /* m    */, 1 /* n    */, 1 /* o    */,
+    1 /* p    */, 1 /* q    */, 1 /* r    */, 1 /* s    */,
+    1 /* t    */, 1 /* u    */, 1 /* v    */, 1 /* w    */,
+    1 /* x    */, 1 /* y    */, 1 /* z    */, 1 /* {    */,
+    1 /* |    */, 1 /* }    */, 1 /* ~    */, 0 /* DEL  */,
+    1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
+    1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
+    1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
+    1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
+    1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
+    1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
+    1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
+    1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
+    1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
+    1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
+    1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
+    1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
+    1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
+    1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
+    1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
+    1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
+    1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
+    1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
+    1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
+    1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */,
+    1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */,
+    1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */,
+    1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
+    1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */,
+    1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */,
+    1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */,
+    1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */,
+    1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
+    1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */,
+    1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */,
+    1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */,
+    1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */
+};
+
+int nghttp2_check_path(const uint8_t *value, size_t len) {
+  const uint8_t *last;
+  for (last = value + len; value != last; ++value) {
+    if (!VALID_PATH_CHARS[*value]) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/* Generated by genauthoritychartbl.py */
 static char VALID_AUTHORITY_CHARS[] = {
     0 /* NUL  */, 0 /* SOH  */, 0 /* STX  */, 0 /* ETX  */,
     0 /* EOT  */, 0 /* ENQ  */, 0 /* ACK  */, 0 /* BEL  */,
index 62f57b6..a2bcd2c 100644 (file)
@@ -360,12 +360,21 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
     return NGHTTP2_ERR_IGN_HTTP_HEADER;
   }
 
-  if (nv->token == NGHTTP2_TOKEN__AUTHORITY ||
-      nv->token == NGHTTP2_TOKEN_HOST) {
+  switch (nv->token) {
+  case NGHTTP2_TOKEN__METHOD:
+    rv = nghttp2_check_method(nv->value->base, nv->value->len);
+    break;
+  case NGHTTP2_TOKEN__PATH:
+    rv = nghttp2_check_path(nv->value->base, nv->value->len);
+    break;
+  case NGHTTP2_TOKEN__AUTHORITY:
+  case NGHTTP2_TOKEN_HOST:
     rv = nghttp2_check_authority(nv->value->base, nv->value->len);
-  } else if (nv->token == NGHTTP2_TOKEN__SCHEME) {
+    break;
+  case NGHTTP2_TOKEN__SCHEME:
     rv = check_scheme(nv->value->base, nv->value->len);
-  } else {
+    break;
+  default:
     rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
   }
 
index 4d9f97b..e5db168 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * nghttp2 - HTTP/2 C Library
  *
- * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ * Copyright (c) 2017 ngtcp2 contributors
+ * Copyright (c) 2012 nghttp2 contributors
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
 #include "nghttp2_map.h"
 
 #include <string.h>
+#include <assert.h>
+#include <stdio.h>
 
-#define INITIAL_TABLE_LENGTH 256
+#include "nghttp2_helper.h"
+
+#define NGHTTP2_INITIAL_TABLE_LENBITS 8
 
 int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
   map->mem = mem;
-  map->tablelen = INITIAL_TABLE_LENGTH;
+  map->tablelen = 1 << NGHTTP2_INITIAL_TABLE_LENBITS;
+  map->tablelenbits = NGHTTP2_INITIAL_TABLE_LENBITS;
   map->table =
-      nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_entry *));
+      nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_bucket));
   if (map->table == NULL) {
     return NGHTTP2_ERR_NOMEM;
   }
@@ -43,112 +49,188 @@ int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
 }
 
 void nghttp2_map_free(nghttp2_map *map) {
+  if (!map) {
+    return;
+  }
+
   nghttp2_mem_free(map->mem, map->table);
 }
 
-void nghttp2_map_each_free(nghttp2_map *map,
-                           int (*func)(nghttp2_map_entry *entry, void *ptr),
+void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
                            void *ptr) {
   uint32_t i;
+  nghttp2_map_bucket *bkt;
+
   for (i = 0; i < map->tablelen; ++i) {
-    nghttp2_map_entry *entry;
-    for (entry = map->table[i]; entry;) {
-      nghttp2_map_entry *next = entry->next;
-      func(entry, ptr);
-      entry = next;
+    bkt = &map->table[i];
+
+    if (bkt->data == NULL) {
+      continue;
     }
-    map->table[i] = NULL;
+
+    func(bkt->data, ptr);
   }
 }
 
-int nghttp2_map_each(nghttp2_map *map,
-                     int (*func)(nghttp2_map_entry *entry, void *ptr),
+int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
                      void *ptr) {
   int rv;
   uint32_t i;
+  nghttp2_map_bucket *bkt;
+
   for (i = 0; i < map->tablelen; ++i) {
-    nghttp2_map_entry *entry;
-    for (entry = map->table[i]; entry; entry = entry->next) {
-      rv = func(entry, ptr);
-      if (rv != 0) {
-        return rv;
-      }
+    bkt = &map->table[i];
+
+    if (bkt->data == NULL) {
+      continue;
+    }
+
+    rv = func(bkt->data, ptr);
+    if (rv != 0) {
+      return rv;
     }
   }
+
   return 0;
 }
 
-void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key) {
-  entry->key = key;
-  entry->next = NULL;
+static uint32_t hash(nghttp2_map_key_type key) {
+  return (uint32_t)key * 2654435769u;
 }
 
-/* Same hash function in android HashMap source code. */
-/* The |mod| must be power of 2 */
-static uint32_t hash(int32_t key, uint32_t mod) {
-  uint32_t h = (uint32_t)key;
-  h ^= (h >> 20) ^ (h >> 12);
-  h ^= (h >> 7) ^ (h >> 4);
-  return h & (mod - 1);
+static size_t h2idx(uint32_t hash, uint32_t bits) {
+  return hash >> (32 - bits);
 }
 
-static int insert(nghttp2_map_entry **table, uint32_t tablelen,
-                  nghttp2_map_entry *entry) {
-  uint32_t h = hash(entry->key, tablelen);
-  if (table[h] == NULL) {
-    table[h] = entry;
-  } else {
-    nghttp2_map_entry *p;
-    /* We won't allow duplicated key, so check it out. */
-    for (p = table[h]; p; p = p->next) {
-      if (p->key == entry->key) {
-        return NGHTTP2_ERR_INVALID_ARGUMENT;
-      }
+static size_t distance(uint32_t tablelen, uint32_t tablelenbits,
+                       nghttp2_map_bucket *bkt, size_t idx) {
+  return (idx - h2idx(bkt->hash, tablelenbits)) & (tablelen - 1);
+}
+
+static void map_bucket_swap(nghttp2_map_bucket *bkt, uint32_t *phash,
+                            nghttp2_map_key_type *pkey, void **pdata) {
+  uint32_t h = bkt->hash;
+  nghttp2_map_key_type key = bkt->key;
+  void *data = bkt->data;
+
+  bkt->hash = *phash;
+  bkt->key = *pkey;
+  bkt->data = *pdata;
+
+  *phash = h;
+  *pkey = key;
+  *pdata = data;
+}
+
+static void map_bucket_set_data(nghttp2_map_bucket *bkt, uint32_t hash,
+                                nghttp2_map_key_type key, void *data) {
+  bkt->hash = hash;
+  bkt->key = key;
+  bkt->data = data;
+}
+
+void nghttp2_map_print_distance(nghttp2_map *map) {
+  uint32_t i;
+  size_t idx;
+  nghttp2_map_bucket *bkt;
+
+  for (i = 0; i < map->tablelen; ++i) {
+    bkt = &map->table[i];
+
+    if (bkt->data == NULL) {
+      fprintf(stderr, "@%u <EMPTY>\n", i);
+      continue;
     }
-    entry->next = table[h];
-    table[h] = entry;
+
+    idx = h2idx(bkt->hash, map->tablelenbits);
+    fprintf(stderr, "@%u hash=%08x key=%d base=%zu distance=%zu\n", i,
+            bkt->hash, bkt->key, idx,
+            distance(map->tablelen, map->tablelenbits, bkt, idx));
+  }
+}
+
+static int insert(nghttp2_map_bucket *table, uint32_t tablelen,
+                  uint32_t tablelenbits, uint32_t hash,
+                  nghttp2_map_key_type key, void *data) {
+  size_t idx = h2idx(hash, tablelenbits);
+  size_t d = 0, dd;
+  nghttp2_map_bucket *bkt;
+
+  for (;;) {
+    bkt = &table[idx];
+
+    if (bkt->data == NULL) {
+      map_bucket_set_data(bkt, hash, key, data);
+      return 0;
+    }
+
+    dd = distance(tablelen, tablelenbits, bkt, idx);
+    if (d > dd) {
+      map_bucket_swap(bkt, &hash, &key, &data);
+      d = dd;
+    } else if (bkt->key == key) {
+      /* TODO This check is just a waste after first swap or if this
+         function is called from map_resize.  That said, there is no
+         difference with or without this conditional in performance
+         wise. */
+      return NGHTTP2_ERR_INVALID_ARGUMENT;
+    }
+
+    ++d;
+    idx = (idx + 1) & (tablelen - 1);
   }
-  return 0;
 }
 
-/* new_tablelen must be power of 2 */
-static int resize(nghttp2_map *map, uint32_t new_tablelen) {
+/* new_tablelen must be power of 2 and new_tablelen == (1 <<
+   new_tablelenbits) must hold. */
+static int map_resize(nghttp2_map *map, uint32_t new_tablelen,
+                      uint32_t new_tablelenbits) {
   uint32_t i;
-  nghttp2_map_entry **new_table;
+  nghttp2_map_bucket *new_table;
+  nghttp2_map_bucket *bkt;
+  int rv;
+  (void)rv;
 
   new_table =
-      nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_entry *));
+      nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_bucket));
   if (new_table == NULL) {
     return NGHTTP2_ERR_NOMEM;
   }
 
   for (i = 0; i < map->tablelen; ++i) {
-    nghttp2_map_entry *entry;
-    for (entry = map->table[i]; entry;) {
-      nghttp2_map_entry *next = entry->next;
-      entry->next = NULL;
-      /* This function must succeed */
-      insert(new_table, new_tablelen, entry);
-      entry = next;
+    bkt = &map->table[i];
+    if (bkt->data == NULL) {
+      continue;
     }
+    rv = insert(new_table, new_tablelen, new_tablelenbits, bkt->hash, bkt->key,
+                bkt->data);
+
+    assert(0 == rv);
   }
+
   nghttp2_mem_free(map->mem, map->table);
   map->tablelen = new_tablelen;
+  map->tablelenbits = new_tablelenbits;
   map->table = new_table;
 
   return 0;
 }
 
-int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) {
+int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
   int rv;
+
+  assert(data);
+
   /* Load factor is 0.75 */
   if ((map->size + 1) * 4 > map->tablelen * 3) {
-    rv = resize(map, map->tablelen * 2);
+    rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1);
     if (rv != 0) {
       return rv;
     }
   }
-  rv = insert(map->table, map->tablelen, new_entry);
+
+  rv = insert(map->table, map->tablelen, map->tablelenbits, hash(key), key,
+              data);
   if (rv != 0) {
     return rv;
   }
@@ -156,34 +238,76 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) {
   return 0;
 }
 
-nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key) {
-  uint32_t h;
-  nghttp2_map_entry *entry;
-  h = hash(key, map->tablelen);
-  for (entry = map->table[h]; entry; entry = entry->next) {
-    if (entry->key == key) {
-      return entry;
+void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) {
+  uint32_t h = hash(key);
+  size_t idx = h2idx(h, map->tablelenbits);
+  nghttp2_map_bucket *bkt;
+  size_t d = 0;
+
+  for (;;) {
+    bkt = &map->table[idx];
+
+    if (bkt->data == NULL ||
+        d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
+      return NULL;
     }
+
+    if (bkt->key == key) {
+      return bkt->data;
+    }
+
+    ++d;
+    idx = (idx + 1) & (map->tablelen - 1);
   }
-  return NULL;
 }
 
-int nghttp2_map_remove(nghttp2_map *map, key_type key) {
-  uint32_t h;
-  nghttp2_map_entry **dst;
+int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
+  uint32_t h = hash(key);
+  size_t idx = h2idx(h, map->tablelenbits), didx;
+  nghttp2_map_bucket *bkt;
+  size_t d = 0;
 
-  h = hash(key, map->tablelen);
+  for (;;) {
+    bkt = &map->table[idx];
 
-  for (dst = &map->table[h]; *dst; dst = &(*dst)->next) {
-    if ((*dst)->key != key) {
-      continue;
+    if (bkt->data == NULL ||
+        d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
+      return NGHTTP2_ERR_INVALID_ARGUMENT;
+    }
+
+    if (bkt->key == key) {
+      map_bucket_set_data(bkt, 0, 0, NULL);
+
+      didx = idx;
+      idx = (idx + 1) & (map->tablelen - 1);
+
+      for (;;) {
+        bkt = &map->table[idx];
+        if (bkt->data == NULL ||
+            distance(map->tablelen, map->tablelenbits, bkt, idx) == 0) {
+          break;
+        }
+
+        map->table[didx] = *bkt;
+        map_bucket_set_data(bkt, 0, 0, NULL);
+        didx = idx;
+
+        idx = (idx + 1) & (map->tablelen - 1);
+      }
+
+      --map->size;
+
+      return 0;
     }
 
-    *dst = (*dst)->next;
-    --map->size;
-    return 0;
+    ++d;
+    idx = (idx + 1) & (map->tablelen - 1);
   }
-  return NGHTTP2_ERR_INVALID_ARGUMENT;
+}
+
+void nghttp2_map_clear(nghttp2_map *map) {
+  memset(map->table, 0, sizeof(*map->table) * map->tablelen);
+  map->size = 0;
 }
 
 size_t nghttp2_map_size(nghttp2_map *map) { return map->size; }
index f6e29e3..1419a09 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * nghttp2 - HTTP/2 C Library
  *
- * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ * Copyright (c) 2017 ngtcp2 contributors
+ * Copyright (c) 2012 nghttp2 contributors
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
 #endif /* HAVE_CONFIG_H */
 
 #include <nghttp2/nghttp2.h>
-#include "nghttp2_int.h"
+
 #include "nghttp2_mem.h"
 
 /* Implementation of unordered map */
 
-typedef int32_t key_type;
+typedef int32_t nghttp2_map_key_type;
 
-typedef struct nghttp2_map_entry {
-  struct nghttp2_map_entry *next;
-  key_type key;
-#if SIZEOF_INT_P == 4
-  /* we requires 8 bytes aligment */
-  int64_t pad;
-#endif
-} nghttp2_map_entry;
+typedef struct nghttp2_map_bucket {
+  uint32_t hash;
+  nghttp2_map_key_type key;
+  void *data;
+} nghttp2_map_bucket;
 
-typedef struct {
-  nghttp2_map_entry **table;
+typedef struct nghttp2_map {
+  nghttp2_map_bucket *table;
   nghttp2_mem *mem;
   size_t size;
   uint32_t tablelen;
+  uint32_t tablelenbits;
 } nghttp2_map;
 
 /*
@@ -74,21 +73,14 @@ void nghttp2_map_free(nghttp2_map *map);
 /*
  * Deallocates each entries using |func| function and any resources
  * allocated for |map|. The |func| function is responsible for freeing
- * given the |entry| object. The |ptr| will be passed to the |func| as
+ * given the |data| object. The |ptr| will be passed to the |func| as
  * send argument. The return value of the |func| will be ignored.
  */
-void nghttp2_map_each_free(nghttp2_map *map,
-                           int (*func)(nghttp2_map_entry *entry, void *ptr),
+void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
                            void *ptr);
 
 /*
- * Initializes the |entry| with the |key|. All entries to be inserted
- * to the map must be initialized with this function.
- */
-void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
-
-/*
- * Inserts the new |entry| with the key |entry->key| to the map |map|.
+ * Inserts the new |data| with the |key| to the map |map|.
  *
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
@@ -98,25 +90,30 @@ void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
  * NGHTTP2_ERR_NOMEM
  *   Out of memory
  */
-int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *entry);
+int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data);
 
 /*
- * Returns the entry associated by the key |key|.  If there is no such
- * entry, this function returns NULL.
+ * Returns the data associated by the key |key|.  If there is no such
+ * data, this function returns NULL.
  */
-nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key);
+void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key);
 
 /*
- * Removes the entry associated by the key |key| from the |map|.  The
- * removed entry is not freed by this function.
+ * Removes the data associated by the key |key| from the |map|.  The
+ * removed data is not freed by this function.
  *
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
  *
  * NGHTTP2_ERR_INVALID_ARGUMENT
- *     The entry associated by |key| does not exist.
+ *     The data associated by |key| does not exist.
  */
-int nghttp2_map_remove(nghttp2_map *map, key_type key);
+int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key);
+
+/*
+ * Removes all entries from |map|.
+ */
+void nghttp2_map_clear(nghttp2_map *map);
 
 /*
  * Returns the number of items stored in the map |map|.
@@ -124,21 +121,22 @@ int nghttp2_map_remove(nghttp2_map *map, key_type key);
 size_t nghttp2_map_size(nghttp2_map *map);
 
 /*
- * Applies the function |func| to each entry in the |map| with the
+ * Applies the function |func| to each data in the |map| with the
  * optional user supplied pointer |ptr|.
  *
  * If the |func| returns 0, this function calls the |func| with the
- * next entry. If the |func| returns nonzero, it will not call the
+ * next data.  If the |func| returns nonzero, it will not call the
  * |func| for further entries and return the return value of the
  * |func| immediately.  Thus, this function returns 0 if all the
  * invocations of the |func| return 0, or nonzero value which the last
  * invocation of |func| returns.
  *
- * Don't use this function to free each entry. Use
+ * Don't use this function to free each data. Use
  * nghttp2_map_each_free() instead.
  */
-int nghttp2_map_each(nghttp2_map *map,
-                     int (*func)(nghttp2_map_entry *entry, void *ptr),
+int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
                      void *ptr);
 
+void nghttp2_map_print_distance(nghttp2_map *map);
+
 #endif /* NGHTTP2_MAP_H */
index 39f81f4..36f1179 100644 (file)
@@ -666,7 +666,7 @@ int nghttp2_session_server_new3(nghttp2_session **session_ptr,
   return 0;
 }
 
-static int free_streams(nghttp2_map_entry *entry, void *ptr) {
+static int free_streams(void *entry, void *ptr) {
   nghttp2_session *session;
   nghttp2_stream *stream;
   nghttp2_outbound_item *item;
@@ -959,6 +959,18 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
     return 0;
   }
 
+  /* Sending RST_STREAM to an idle stream is subject to protocol
+     violation.  Historically, nghttp2 allows this.  In order not to
+     disrupt the existing applications, we don't error out this case
+     and simply ignore it. */
+  if (nghttp2_session_is_my_stream_id(session, stream_id)) {
+    if ((uint32_t)stream_id >= session->next_stream_id) {
+      return 0;
+    }
+  } else if (session->last_recv_stream_id < stream_id) {
+    return 0;
+  }
+
   /* Cancel pending request HEADERS in ob_syn if this RST_STREAM
      refers to that stream. */
   if (!session->server && nghttp2_session_is_my_stream_id(session, stream_id) &&
@@ -969,8 +981,7 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
     headers_frame = &nghttp2_outbound_queue_top(&session->ob_syn)->frame;
     assert(headers_frame->hd.type == NGHTTP2_HEADERS);
 
-    if (headers_frame->hd.stream_id <= stream_id &&
-        (uint32_t)stream_id < session->next_stream_id) {
+    if (headers_frame->hd.stream_id <= stream_id) {
 
       for (item = session->ob_syn.head; item; item = item->qnext) {
         aux_data = &item->aux_data.headers;
@@ -1091,7 +1102,7 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
                         (int32_t)session->local_settings.initial_window_size,
                         stream_user_data, mem);
 
-    rv = nghttp2_map_insert(&session->streams, &stream->map_entry);
+    rv = nghttp2_map_insert(&session->streams, stream_id, stream);
     if (rv != 0) {
       nghttp2_stream_free(stream);
       nghttp2_mem_free(mem, stream);
@@ -2413,7 +2424,7 @@ static int session_call_on_frame_send(nghttp2_session *session,
   return 0;
 }
 
-static int find_stream_on_goaway_func(nghttp2_map_entry *entry, void *ptr) {
+static int find_stream_on_goaway_func(void *entry, void *ptr) {
   nghttp2_close_stream_on_goaway_arg *arg;
   nghttp2_stream *stream;
 
@@ -4183,8 +4194,7 @@ static int session_process_rst_stream_frame(nghttp2_session *session) {
   return nghttp2_session_on_rst_stream_received(session, frame);
 }
 
-static int update_remote_initial_window_size_func(nghttp2_map_entry *entry,
-                                                  void *ptr) {
+static int update_remote_initial_window_size_func(void *entry, void *ptr) {
   int rv;
   nghttp2_update_window_size_arg *arg;
   nghttp2_stream *stream;
@@ -4237,8 +4247,7 @@ session_update_remote_initial_window_size(nghttp2_session *session,
                           update_remote_initial_window_size_func, &arg);
 }
 
-static int update_local_initial_window_size_func(nghttp2_map_entry *entry,
-                                                 void *ptr) {
+static int update_local_initial_window_size_func(void *entry, void *ptr) {
   int rv;
   nghttp2_update_window_size_arg *arg;
   nghttp2_stream *stream;
@@ -5353,9 +5362,11 @@ static ssize_t inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe,
   return (ssize_t)(readlen);
 }
 
+static const uint8_t static_in[] = {0};
+
 ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
                                  size_t inlen) {
-  const uint8_t *first = in, *last = in + inlen;
+  const uint8_t *first, *last;
   nghttp2_inbound_frame *iframe = &session->iframe;
   size_t readlen;
   ssize_t padlen;
@@ -5366,6 +5377,14 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
   size_t pri_fieldlen;
   nghttp2_mem *mem;
 
+  if (in == NULL) {
+    assert(inlen == 0);
+    in = static_in;
+  }
+
+  first = in;
+  last = in + inlen;
+
   DEBUGF("recv: connection recv_window_size=%d, local_window=%d\n",
          session->recv_window_size, session->local_window_size);
 
@@ -6411,8 +6430,9 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
 
       /* CONTINUATION won't bear NGHTTP2_PADDED flag */
 
-      iframe->frame.hd.flags = (uint8_t)(
-          iframe->frame.hd.flags | (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS));
+      iframe->frame.hd.flags =
+          (uint8_t)(iframe->frame.hd.flags |
+                    (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS));
       iframe->frame.hd.length += cont_hd.length;
 
       busy = 1;
@@ -7448,8 +7468,8 @@ static int nghttp2_session_upgrade_internal(nghttp2_session *session,
     return NGHTTP2_ERR_INVALID_ARGUMENT;
   }
   /* SETTINGS frame contains too many settings */
-  if (settings_payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH
-        > session->max_settings) {
+  if (settings_payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH >
+      session->max_settings) {
     return NGHTTP2_ERR_TOO_MANY_SETTINGS;
   }
   rv = nghttp2_frame_unpack_settings_payload2(&iv, &niv, settings_payload,
index dc3a6b1..96e1d9f 100644 (file)
@@ -62,7 +62,6 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
                          int32_t weight, int32_t remote_initial_window_size,
                          int32_t local_initial_window_size,
                          void *stream_user_data, nghttp2_mem *mem) {
-  nghttp2_map_entry_init(&stream->map_entry, (key_type)stream_id);
   nghttp2_pq_init(&stream->obq, stream_less, mem);
 
   stream->stream_id = stream_id;
index a1b807d..2846c6a 100644 (file)
@@ -135,8 +135,6 @@ typedef enum {
 } nghttp2_http_flag;
 
 struct nghttp2_stream {
-  /* Intrusive Map */
-  nghttp2_map_entry map_entry;
   /* Entry for dep_prev->obq */
   nghttp2_pq_entry pq_entry;
   /* Priority Queue storing direct descendant (nghttp2_stream).  Only
old mode 100644 (file)
new mode 100755 (executable)
index 0cb7f90..21e5e07
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-14"
+VERSION="2.4.6 Debian-2.4.6-15"
 package_revision=2.4.6
 
 
@@ -2141,7 +2141,7 @@ include the following information:
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion Debian-2.4.6-14
+       version:        $progname $scriptversion Debian-2.4.6-15
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
index 067fbcf..9d4eecf 100644 (file)
@@ -1,5 +1,5 @@
 # ===========================================================================
-#      http://www.gnu.org/software/autoconf-archive/ax_python_devel.html
+#     https://www.gnu.org/software/autoconf-archive/ax_python_devel.html
 # ===========================================================================
 #
 # SYNOPSIS
@@ -12,8 +12,8 @@
 #   in your configure.ac.
 #
 #   This macro checks for Python and tries to get the include path to
-#   'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS)
-#   output variables. It also exports $(PYTHON_EXTRA_LIBS) and
+#   'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output
+#   variables. It also exports $(PYTHON_EXTRA_LIBS) and
 #   $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code.
 #
 #   You can search for some particular version of Python by passing a
@@ -52,7 +52,7 @@
 #   Public License for more details.
 #
 #   You should have received a copy of the GNU General Public License along
-#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#   with this program. If not, see <https://www.gnu.org/licenses/>.
 #
 #   As a special exception, the respective Autoconf Macro's copyright owner
 #   gives unlimited permission to copy, distribute and modify the configure
@@ -67,7 +67,7 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 16
+#serial 23
 
 AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
 AC_DEFUN([AX_PYTHON_DEVEL],[
@@ -81,12 +81,10 @@ AC_DEFUN([AX_PYTHON_DEVEL],[
 
        AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
        if test -z "$PYTHON"; then
-          AC_MSG_WARN([Cannot find python$PYTHON_VERSION in your system path])
+          AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
           PYTHON_VERSION=""
-           no_python_devel=yes
        fi
 
-AS_IF([test -z "$no_python_devel"], [
        #
        # Check for a version of Python >= 2.1.0
        #
@@ -97,25 +95,22 @@ AS_IF([test -z "$no_python_devel"], [
        if test "$ac_supports_python_ver" != "True"; then
                if test -z "$PYTHON_NOVERSIONCHECK"; then
                        AC_MSG_RESULT([no])
-                       AC_MSG_WARN([
+                       AC_MSG_FAILURE([
 This version of the AC@&t@_PYTHON_DEVEL macro
 doesn't work properly with versions of Python before
 2.1.0. You may need to re-run configure, setting the
-variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
+variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG,
 PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
 Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
 to something else than an empty string.
 ])
-                        no_python_devel=yes
                else
                        AC_MSG_RESULT([skip at user request])
                fi
        else
                AC_MSG_RESULT([yes])
        fi
-]) # AS_IF
 
-AS_IF([test -z "$no_python_devel"], [
        #
        # if the macro parameter ``version'' is set, honour it
        #
@@ -128,45 +123,57 @@ AS_IF([test -z "$no_python_devel"], [
                   AC_MSG_RESULT([yes])
                else
                        AC_MSG_RESULT([no])
-                       AC_MSG_WARN([this package requires Python $1.
+                       AC_MSG_ERROR([this package requires Python $1.
 If you have it installed, but it isn't the default Python
 interpreter in your system path, please pass the PYTHON_VERSION
 variable to configure. See ``configure --help'' for reference.
 ])
                        PYTHON_VERSION=""
-                        no_python_devel=yes
                fi
        fi
-]) # AS_IF
 
-AS_IF([test -z "$no_python_devel"], [
        #
        # Check if you have distutils, else fail
        #
-       AC_MSG_CHECKING([for the distutils Python package])
-       ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
-       if test -z "$ac_distutils_result"; then
+       AC_MSG_CHECKING([for the sysconfig Python package])
+       ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1`
+       if test $? -eq 0; then
                AC_MSG_RESULT([yes])
+               IMPORT_SYSCONFIG="import sysconfig"
        else
                AC_MSG_RESULT([no])
-               AC_MSG_WARN([cannot import Python module "distutils".
+
+               AC_MSG_CHECKING([for the distutils Python package])
+               ac_sysconfig_result=`$PYTHON -c "from distutils import sysconfig" 2>&1`
+               if test $? -eq 0; then
+                       AC_MSG_RESULT([yes])
+                       IMPORT_SYSCONFIG="from distutils import sysconfig"
+               else
+                       AC_MSG_ERROR([cannot import Python module "distutils".
 Please check your Python installation. The error was:
-$ac_distutils_result])
-               PYTHON_VERSION=""
-                no_python_devel=yes
+$ac_sysconfig_result])
+                       PYTHON_VERSION=""
+               fi
        fi
-]) # AS_IF
 
-AS_IF([test -z "$no_python_devel"], [
        #
        # Check for Python include path
        #
        AC_MSG_CHECKING([for Python include path])
        if test -z "$PYTHON_CPPFLAGS"; then
-               python_path=`$PYTHON -c "import distutils.sysconfig; \
-                       print (distutils.sysconfig.get_python_inc ());"`
-               plat_python_path=`$PYTHON -c "import distutils.sysconfig; \
-                       print (distutils.sysconfig.get_python_inc (plat_specific=1));"`
+               if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
+                       # sysconfig module has different functions
+                       python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_path ('include'));"`
+                       plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_path ('platinclude'));"`
+               else
+                       # old distutils way
+                       python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_python_inc ());"`
+                       plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_python_inc (plat_specific=1));"`
+               fi
                if test -n "${python_path}"; then
                        if test "${plat_python_path}" != "${python_path}"; then
                                python_path="-I$python_path -I$plat_python_path"
@@ -183,14 +190,14 @@ AS_IF([test -z "$no_python_devel"], [
        # Check for Python library path
        #
        AC_MSG_CHECKING([for Python library path])
-       if test -z "$PYTHON_LDFLAGS"; then
+       if test -z "$PYTHON_LIBS"; then
                # (makes two attempts to ensure we've got a version number
                # from the interpreter)
                ac_python_version=`cat<<EOD | $PYTHON -
 
 # join all versioning strings, on some systems
 # major/minor numbers could be in different list elements
-from distutils.sysconfig import *
+from sysconfig import *
 e = get_config_var('VERSION')
 if e is not None:
        print(e)
@@ -213,8 +220,8 @@ EOD`
                ac_python_libdir=`cat<<EOD | $PYTHON -
 
 # There should be only one
-import distutils.sysconfig
-e = distutils.sysconfig.get_config_var('LIBDIR')
+$IMPORT_SYSCONFIG
+e = sysconfig.get_config_var('LIBDIR')
 if e is not None:
        print (e)
 EOD`
@@ -222,8 +229,8 @@ EOD`
                # Now, for the library:
                ac_python_library=`cat<<EOD | $PYTHON -
 
-import distutils.sysconfig
-c = distutils.sysconfig.get_config_vars()
+$IMPORT_SYSCONFIG
+c = sysconfig.get_config_vars()
 if 'LDVERSION' in c:
        print ('python'+c[['LDVERSION']])
 else:
@@ -238,48 +245,68 @@ EOD`
                then
                        # use the official shared library
                        ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
-                       PYTHON_LDFLAGS="-L$ac_python_libdir -l$ac_python_library"
+                       PYTHON_LIBS="-L$ac_python_libdir -l$ac_python_library"
                else
                        # old way: use libpython from python_configdir
                        ac_python_libdir=`$PYTHON -c \
-                         "from distutils.sysconfig import get_python_lib as f; \
+                         "from sysconfig import get_python_lib as f; \
                          import os; \
                          print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
-                       PYTHON_LDFLAGS="-L$ac_python_libdir -lpython$ac_python_version"
+                       PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version"
                fi
 
-               if test -z "PYTHON_LDFLAGS"; then
-                       AC_MSG_WARN([
+               if test -z "PYTHON_LIBS"; then
+                       AC_MSG_ERROR([
   Cannot determine location of your Python DSO. Please check it was installed with
-  dynamic libraries enabled, or try setting PYTHON_LDFLAGS by hand.
+  dynamic libraries enabled, or try setting PYTHON_LIBS by hand.
                        ])
-                        no_python_devel=yes
                fi
        fi
-       AC_MSG_RESULT([$PYTHON_LDFLAGS])
-       AC_SUBST([PYTHON_LDFLAGS])
-]) # AS_IF
+       AC_MSG_RESULT([$PYTHON_LIBS])
+       AC_SUBST([PYTHON_LIBS])
 
-AS_IF([test -z "$no_python_devel"], [
        #
        # Check for site packages
        #
        AC_MSG_CHECKING([for Python site-packages path])
        if test -z "$PYTHON_SITE_PKG"; then
-               PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
-                       print (distutils.sysconfig.get_python_lib(0,0));"`
+               if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
+                       PYTHON_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_path('purelib'));"`
+               else
+                       # distutils.sysconfig way
+                       PYTHON_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_python_lib(0,0));"`
+               fi
        fi
        AC_MSG_RESULT([$PYTHON_SITE_PKG])
        AC_SUBST([PYTHON_SITE_PKG])
 
        #
+       # Check for platform-specific site packages
+       #
+       AC_MSG_CHECKING([for Python platform specific site-packages path])
+       if test -z "$PYTHON_SITE_PKG"; then
+               if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
+                       PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_path('platlib'));"`
+               else
+                       # distutils.sysconfig way
+                       PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                               print (sysconfig.get_python_lib(1,0));"`
+               fi
+       fi
+       AC_MSG_RESULT([$PYTHON_PLATFORM_SITE_PKG])
+       AC_SUBST([PYTHON_PLATFORM_SITE_PKG])
+
+       #
        # libraries which must be linked in when embedding
        #
        AC_MSG_CHECKING(python extra libraries)
        if test -z "$PYTHON_EXTRA_LIBS"; then
-          PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
-                conf = distutils.sysconfig.get_config_var; \
-                print (conf('LIBS'))"`
+          PYTHON_EXTRA_LIBS=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                conf = sysconfig.get_config_var; \
+                print (conf('LIBS') + ' ' + conf('SYSLIBS'))"`
        fi
        AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
        AC_SUBST(PYTHON_EXTRA_LIBS)
@@ -289,8 +316,8 @@ AS_IF([test -z "$no_python_devel"], [
        #
        AC_MSG_CHECKING(python extra linking flags)
        if test -z "$PYTHON_EXTRA_LDFLAGS"; then
-               PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
-                       conf = distutils.sysconfig.get_config_var; \
+               PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "$IMPORT_SYSCONFIG; \
+                       conf = sysconfig.get_config_var; \
                        print (conf('LINKFORSHARED'))"`
        fi
        AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
@@ -302,8 +329,10 @@ AS_IF([test -z "$no_python_devel"], [
        AC_MSG_CHECKING([consistency of all components of python development environment])
        # save current global flags
        ac_save_LIBS="$LIBS"
+       ac_save_LDFLAGS="$LDFLAGS"
        ac_save_CPPFLAGS="$CPPFLAGS"
-       LIBS="$ac_save_LIBS $PYTHON_LDFLAGS $PYTHON_EXTRA_LDFLAGS $PYTHON_EXTRA_LIBS"
+       LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_EXTRA_LIBS"
+       LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS"
        CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
        AC_LANG_PUSH([C])
        AC_LINK_IFELSE([
@@ -314,15 +343,16 @@ AS_IF([test -z "$no_python_devel"], [
        # turn back to default flags
        CPPFLAGS="$ac_save_CPPFLAGS"
        LIBS="$ac_save_LIBS"
+       LDFLAGS="$ac_save_LDFLAGS"
 
        AC_MSG_RESULT([$pythonexists])
 
         if test ! "x$pythonexists" = "xyes"; then
-          AC_MSG_WARN([
+          AC_MSG_FAILURE([
   Could not link test program to Python. Maybe the main Python library has been
   installed in some non-standard library path. If so, pass it to configure,
-  via the LDFLAGS environment variable.
-  Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
+  via the LIBS environment variable.
+  Example: ./configure LIBS="-L/usr/non-standard-path/python/lib"
   ============================================================================
    ERROR!
    You probably have to install the development version of the Python package
@@ -330,15 +360,9 @@ AS_IF([test -z "$no_python_devel"], [
   ============================================================================
           ])
          PYTHON_VERSION=""
-          no_python_devel=yes
        fi
 
        #
        # all done!
        #
-]) # AS_IF
-
-AS_IF([test -z "$no_python_devel"],
-      [have_python_dev=yes], [have_python_dev=no])
-
-]) # AS_IF
+])
index a6d21ae..c4c0294 100644 (file)
@@ -1071,11 +1071,11 @@ _LT_EOF
       # to the OS version, if on x86, and 10.4, the deployment
       # target defaults to 10.4. Don't you love it?
       case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
-       10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+       10.0,*86*-darwin8*|10.0,*-darwin[[912]]*)
          _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
        10.[[012]][[,.]]*)
          _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
-       10.*)
+       10.*|11.*)
          _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
       esac
     ;;
diff --git a/missing b/missing
index 625aeb1..1fe1611 100755 (executable)
--- a/missing
+++ b/missing
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
index 2d2edd5..75eb7a0 100644 (file)
@@ -44,6 +44,6 @@ clean-local:
        -rm -f $(builddir)/nghttp2.c
 
 .pyx.c:
-       $(CYTHON) -o $@ $<
+       $(CYTHON) -3 -o $@ $<
 
 endif # ENABLE_PYTHON_BINDINGS
index 709bc6f..29236e7 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -166,11 +166,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -189,8 +192,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -201,9 +207,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -212,9 +221,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -252,8 +270,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -380,7 +399,6 @@ ctags CTAGS:
 
 cscope cscopelist:
 
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -449,9 +467,9 @@ distclean-generic:
 maintainer-clean-generic:
        @echo "This command is intended for maintainers to use"
        @echo "it deletes files that may require special tools to rebuild."
+@ENABLE_PYTHON_BINDINGS_FALSE@clean-local:
 @ENABLE_PYTHON_BINDINGS_FALSE@install-exec-local:
 @ENABLE_PYTHON_BINDINGS_FALSE@uninstall-local:
-@ENABLE_PYTHON_BINDINGS_FALSE@clean-local:
 clean: clean-am
 
 clean-am: clean-generic clean-libtool clean-local mostlyclean-am
@@ -555,7 +573,7 @@ uninstall-am: uninstall-local
 @ENABLE_PYTHON_BINDINGS_TRUE@  -rm -f $(builddir)/nghttp2.c
 
 @ENABLE_PYTHON_BINDINGS_TRUE@.pyx.c:
-@ENABLE_PYTHON_BINDINGS_TRUE@  $(CYTHON) -o $@ $<
+@ENABLE_PYTHON_BINDINGS_TRUE@  $(CYTHON) -3 -o $@ $<
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
index 7821ff1..c374d78 100644 (file)
@@ -857,7 +857,7 @@ cdef class _HTTP2SessionCore(_HTTP2SessionCoreBase):
 
         rv = cnghttp2.nghttp2_submit_settings(self.session,
                                               cnghttp2.NGHTTP2_FLAG_NONE,
-                                              iv, sizeof(iv) / sizeof(iv[0]))
+                                              iv, sizeof(iv) // sizeof(iv[0]))
 
         if rv != 0:
             raise Exception('nghttp2_submit_settings failed: {}'.format\
@@ -971,7 +971,7 @@ cdef class _HTTP2ClientSessionCore(_HTTP2SessionCoreBase):
 
         rv = cnghttp2.nghttp2_submit_settings(self.session,
                                               cnghttp2.NGHTTP2_FLAG_NONE,
-                                              iv, sizeof(iv) / sizeof(iv[0]))
+                                              iv, sizeof(iv) // sizeof(iv[0]))
 
         if rv != 0:
             raise Exception('nghttp2_submit_settings failed: {}'.format\
index 672f81b..f8d335b 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -197,11 +197,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -220,8 +223,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -232,9 +238,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -243,9 +252,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -283,8 +301,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -444,7 +463,6 @@ ctags CTAGS:
 
 cscope cscopelist:
 
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
index 12e9e78..8057de1 100644 (file)
@@ -15,10 +15,14 @@ include_directories(
   ${JEMALLOC_INCLUDE_DIRS}
   ${LIBXML2_INCLUDE_DIRS}
   ${LIBEV_INCLUDE_DIRS}
+  ${LIBNGHTTP3_INCLUDE_DIRS}
+  ${LIBNGTCP2_INCLUDE_DIRS}
+  ${LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIRS}
   ${OPENSSL_INCLUDE_DIRS}
   ${LIBCARES_INCLUDE_DIRS}
   ${JANSSON_INCLUDE_DIRS}
   ${ZLIB_INCLUDE_DIRS}
+  ${LIBBPF_INCLUDE_DIRS}
 )
 
 # XXX per-target?
@@ -27,11 +31,15 @@ link_libraries(
   ${JEMALLOC_LIBRARIES}
   ${LIBXML2_LIBRARIES}
   ${LIBEV_LIBRARIES}
+  ${LIBNGHTTP3_LIBRARIES}
+  ${LIBNGTCP2_LIBRARIES}
+  ${LIBNGTCP2_CRYPTO_OPENSSL_LIBRARIES}
   ${OPENSSL_LIBRARIES}
   ${LIBCARES_LIBRARIES}
   ${JANSSON_LIBRARIES}
   ${ZLIB_LIBRARIES}
   ${APP_LIBRARIES}
+  ${LIBBPF_LIBRARIES}
 )
 
 if(ENABLE_APP)
@@ -67,7 +75,13 @@ if(ENABLE_APP)
     h2load_http2_session.cc
     h2load_http1_session.cc
   )
-
+  if(ENABLE_HTTP3)
+    list(APPEND H2LOAD_SOURCES
+      h2load_http3_session.cc
+      h2load_quic.cc
+      quic.cc
+    )
+  endif()
 
   # Common libnhttpx sources (used for nghttpx and unit tests)
   set(NGHTTPX_SRCS
@@ -104,6 +118,7 @@ if(ENABLE_APP)
     shrpx_router.cc
     shrpx_api_downstream_connection.cc
     shrpx_health_monitor_downstream_connection.cc
+    shrpx_null_downstream_connection.cc
     shrpx_exec.cc
     shrpx_dns_resolver.cc
     shrpx_dual_dns_resolver.cc
@@ -119,6 +134,16 @@ if(ENABLE_APP)
       shrpx_mruby_module_response.cc
     )
   endif()
+  if(ENABLE_HTTP3)
+    list(APPEND NGHTTPX_SRCS
+     shrpx_quic.cc
+     shrpx_quic_listener.cc
+     shrpx_quic_connection_handler.cc
+     shrpx_http3_upstream.cc
+     http3.cc
+     quic.cc
+    )
+  endif()
   add_library(nghttpx_static STATIC ${NGHTTPX_SRCS})
   set_target_properties(nghttpx_static PROPERTIES ARCHIVE_OUTPUT_NAME nghttpx)
 
@@ -189,7 +214,10 @@ if(ENABLE_APP)
   add_executable(nghttpx  ${NGHTTPX-bin_SOURCES} $<TARGET_OBJECTS:llhttp>
     $<TARGET_OBJECTS:url-parser>
   )
-  target_compile_definitions(nghttpx PRIVATE "-DPKGDATADIR=\"${PKGDATADIR}\"")
+  target_compile_definitions(nghttpx PRIVATE
+    "-DPKGDATADIR=\"${PKGDATADIR}\""
+    "-DPKGLIBDIR=\"${PKGLIBDIR}\""
+  )
   target_link_libraries(nghttpx nghttpx_static)
   add_executable(h2load   ${H2LOAD_SOURCES}   $<TARGET_OBJECTS:llhttp>
     $<TARGET_OBJECTS:url-parser>
index 5075bc9..e82310e 100644 (file)
 #include <mutex>
 #include <deque>
 
+#include "ssl_compat.h"
+
 #include <openssl/err.h>
 #include <openssl/dh.h>
+#if OPENSSL_3_0_0_API
+#  include <openssl/decoder.h>
+#endif // OPENSSL_3_0_0_API
 
 #include <zlib.h>
 
@@ -2105,7 +2110,7 @@ int HttpServer::run() {
   std::vector<unsigned char> next_proto;
 
   if (!config_->no_tls) {
-    ssl_ctx = SSL_CTX_new(SSLv23_server_method());
+    ssl_ctx = SSL_CTX_new(TLS_server_method());
     if (!ssl_ctx) {
       std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
       return -1;
@@ -2138,15 +2143,13 @@ int HttpServer::run() {
     SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_SERVER);
 
 #ifndef OPENSSL_NO_EC
-
-    // Disabled SSL_CTX_set_ecdh_auto, because computational cost of
-    // chosen curve is much higher than P-256.
-
-    // #if OPENSSL_VERSION_NUMBER >= 0x10002000L
-    //     SSL_CTX_set_ecdh_auto(ssl_ctx, 1);
-    // #else // OPENSSL_VERSION_NUBMER < 0x10002000L
-    // Use P-256, which is sufficiently secure at the time of this
-    // writing.
+#  if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L
+    if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) {
+      std::cerr << "SSL_CTX_set1_curves_list failed: "
+                << ERR_error_string(ERR_get_error(), nullptr);
+      return -1;
+    }
+#  else  // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L)
     auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
     if (ecdh == nullptr) {
       std::cerr << "EC_KEY_new_by_curv_name failed: "
@@ -2155,19 +2158,36 @@ int HttpServer::run() {
     }
     SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
     EC_KEY_free(ecdh);
-    // #endif // OPENSSL_VERSION_NUBMER < 0x10002000L
-
-#endif // OPENSSL_NO_EC
+#  endif // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L)
+#endif   // OPENSSL_NO_EC
 
     if (!config_->dh_param_file.empty()) {
       // Read DH parameters from file
-      auto bio = BIO_new_file(config_->dh_param_file.c_str(), "r");
+      auto bio = BIO_new_file(config_->dh_param_file.c_str(), "rb");
       if (bio == nullptr) {
         std::cerr << "BIO_new_file() failed: "
                   << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
         return -1;
       }
 
+#if OPENSSL_3_0_0_API
+      EVP_PKEY *dh = nullptr;
+      auto dctx = OSSL_DECODER_CTX_new_for_pkey(
+          &dh, "PEM", nullptr, "DH", OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+          nullptr, nullptr);
+
+      if (!OSSL_DECODER_from_bio(dctx, bio)) {
+        std::cerr << "OSSL_DECODER_from_bio() failed: "
+                  << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
+        return -1;
+      }
+
+      if (SSL_CTX_set0_tmp_dh_pkey(ssl_ctx, dh) != 1) {
+        std::cerr << "SSL_CTX_set0_tmp_dh_pkey failed: "
+                  << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
+        return -1;
+      }
+#else  // !OPENSSL_3_0_0_API
       auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
 
       if (dh == nullptr) {
@@ -2178,6 +2198,7 @@ int HttpServer::run() {
 
       SSL_CTX_set_tmp_dh(ssl_ctx, dh);
       DH_free(dh);
+#endif // !OPENSSL_3_0_0_API
       BIO_free(bio);
     }
 
index db2137b..0de90e4 100644 (file)
@@ -242,7 +242,7 @@ private:
 };
 
 ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
-                           uint8_t *buf, size_t length, int *eof,
+                           uint8_t *buf, size_t length, uint32_t *data_flags,
                            nghttp2_data_source *source, void *user_data);
 
 } // namespace nghttp2
index 0382164..2fd6ead 100644 (file)
@@ -35,19 +35,28 @@ AM_CFLAGS = $(WARNCFLAGS)
 AM_CXXFLAGS = $(WARNCXXFLAGS) $(CXX1XCXXFLAGS)
 AM_CPPFLAGS = \
        -DPKGDATADIR='"$(pkgdatadir)"' \
+       -DPKGLIBDIR='"$(pkglibdir)"' \
        -I$(top_srcdir)/lib/includes \
        -I$(top_builddir)/lib/includes \
        -I$(top_srcdir)/lib \
        -I$(top_srcdir)/src/includes \
        -I$(top_srcdir)/third-party \
        -I$(top_srcdir)/third-party/llhttp/include \
+       @JEMALLOC_CFLAGS@ \
        @LIBXML2_CFLAGS@ \
        @LIBEV_CFLAGS@ \
+       @LIBNGHTTP3_CFLAGS@ \
+       @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@ \
+       @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@ \
+       @LIBNGTCP2_CFLAGS@ \
        @OPENSSL_CFLAGS@ \
        @LIBCARES_CFLAGS@ \
        @JANSSON_CFLAGS@ \
+       @LIBBPF_CFLAGS@ \
        @ZLIB_CFLAGS@ \
+       @EXTRA_DEFS@ \
        @DEFS@
+AM_LDFLAGS = @LIBTOOL_LDFLAGS@
 
 LDADD = $(top_builddir)/lib/libnghttp2.la \
        $(top_builddir)/third-party/liburl-parser.la \
@@ -55,10 +64,15 @@ LDADD = $(top_builddir)/lib/libnghttp2.la \
        @JEMALLOC_LIBS@ \
        @LIBXML2_LIBS@ \
        @LIBEV_LIBS@ \
+       @LIBNGHTTP3_LIBS@ \
+       @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@ \
+       @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@ \
+       @LIBNGTCP2_LIBS@ \
        @OPENSSL_LIBS@ \
        @LIBCARES_LIBS@ \
        @SYSTEMD_LIBS@ \
        @JANSSON_LIBS@ \
+       @LIBBPF_LIBS@ \
        @ZLIB_LIBS@ \
        @APPLDFLAGS@
 
@@ -97,6 +111,13 @@ h2load_SOURCES = util.cc util.h \
        h2load_http2_session.cc h2load_http2_session.h \
        h2load_http1_session.cc h2load_http1_session.h
 
+if ENABLE_HTTP3
+h2load_SOURCES += \
+       h2load_http3_session.cc h2load_http3_session.h \
+       h2load_quic.cc h2load_quic.h \
+       quic.cc quic.h
+endif # ENABLE_HTTP3
+
 NGHTTPX_SRCS = \
        util.cc util.h http2.cc http2.h timegm.c timegm.h base64.h \
        app_helper.cc app_helper.h \
@@ -137,6 +158,7 @@ NGHTTPX_SRCS = \
        shrpx_api_downstream_connection.cc shrpx_api_downstream_connection.h \
        shrpx_health_monitor_downstream_connection.cc \
        shrpx_health_monitor_downstream_connection.h \
+       shrpx_null_downstream_connection.cc shrpx_null_downstream_connection.h \
        shrpx_exec.cc shrpx_exec.h \
        shrpx_dns_resolver.cc shrpx_dns_resolver.h \
        shrpx_dual_dns_resolver.cc shrpx_dual_dns_resolver.h \
@@ -153,6 +175,16 @@ NGHTTPX_SRCS += \
        shrpx_mruby_module_response.cc shrpx_mruby_module_response.h
 endif # HAVE_MRUBY
 
+if ENABLE_HTTP3
+NGHTTPX_SRCS += \
+       shrpx_quic.cc shrpx_quic.h \
+       shrpx_quic_listener.cc shrpx_quic_listener.h \
+       shrpx_quic_connection_handler.cc shrpx_quic_connection_handler.h \
+       shrpx_http3_upstream.cc shrpx_http3_upstream.h \
+       http3.cc http3.h \
+       quic.cc quic.h
+endif # ENABLE_HTTP3
+
 noinst_LIBRARIES = libnghttpx.a
 libnghttpx_a_SOURCES = ${NGHTTPX_SRCS}
 libnghttpx_a_CPPFLAGS = ${AM_CPPFLAGS}
@@ -262,7 +294,7 @@ libnghttp2_asio_la_SOURCES = \
        asio_client_tls_context.cc asio_client_tls_context.h
 
 libnghttp2_asio_la_CPPFLAGS = ${AM_CPPFLAGS} ${BOOST_CPPFLAGS}
-libnghttp2_asio_la_LDFLAGS = -no-undefined -version-info 1:0:0
+libnghttp2_asio_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 1:0:0
 libnghttp2_asio_la_LIBADD = \
        $(top_builddir)/lib/libnghttp2.la \
        $(top_builddir)/third-party/liburl-parser.la \
index f4d16c9..dc4c048 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -112,30 +112,43 @@ check_PROGRAMS = $(am__EXEEXT_3)
 TESTS = $(am__EXEEXT_3)
 @ENABLE_APP_TRUE@am__append_1 = nghttp nghttpd nghttpx h2load
 @ENABLE_APP_TRUE@@HAVE_LIBXML2_TRUE@am__append_2 = HtmlParser.cc
-@ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@am__append_3 = \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@am__append_3 = \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   h2load_http3_session.cc h2load_http3_session.h \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   h2load_quic.cc h2load_quic.h \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   quic.cc quic.h
+
+@ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@am__append_4 = \
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@     shrpx_mruby.cc shrpx_mruby.h \
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@     shrpx_mruby_module.cc shrpx_mruby_module.h \
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@     shrpx_mruby_module_env.cc shrpx_mruby_module_env.h \
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@     shrpx_mruby_module_request.cc shrpx_mruby_module_request.h \
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@     shrpx_mruby_module_response.cc shrpx_mruby_module_response.h
 
-@ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@am__append_4 = \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@am__append_5 = \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   shrpx_quic.cc shrpx_quic.h \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   shrpx_quic_listener.cc shrpx_quic_listener.h \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   shrpx_quic_connection_handler.cc shrpx_quic_connection_handler.h \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   shrpx_http3_upstream.cc shrpx_http3_upstream.h \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   http3.cc http3.h \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   quic.cc quic.h
+
+@ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@am__append_6 = \
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@     -I${top_srcdir}/third-party/mruby/include @LIBMRUBY_CFLAGS@
 
-@ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@am__append_5 = -L${top_builddir}/third-party/mruby/build/lib @LIBMRUBY_LIBS@
-@ENABLE_APP_TRUE@@HAVE_NEVERBLEED_TRUE@am__append_6 = -I${top_srcdir}/third-party/neverbleed
-@ENABLE_APP_TRUE@@HAVE_NEVERBLEED_TRUE@am__append_7 = ${top_builddir}/third-party/libneverbleed.la
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@am__append_8 = nghttpx-unittest
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@@HAVE_MRUBY_TRUE@am__append_9 = \
+@ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@am__append_7 = -L${top_builddir}/third-party/mruby/build/lib @LIBMRUBY_LIBS@
+@ENABLE_APP_TRUE@@HAVE_NEVERBLEED_TRUE@am__append_8 = -I${top_srcdir}/third-party/neverbleed
+@ENABLE_APP_TRUE@@HAVE_NEVERBLEED_TRUE@am__append_9 = ${top_builddir}/third-party/libneverbleed.la
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@am__append_10 = nghttpx-unittest
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@@HAVE_MRUBY_TRUE@am__append_11 = \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@@HAVE_MRUBY_TRUE@    -I${top_srcdir}/third-party/mruby/include @LIBMRUBY_CFLAGS@
 
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@@HAVE_MRUBY_TRUE@am__append_10 = \
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@@HAVE_MRUBY_TRUE@am__append_12 = \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@@HAVE_MRUBY_TRUE@    -L${top_builddir}/third-party/mruby/build/lib @LIBMRUBY_LIBS@
 
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@@HAVE_NEVERBLEED_TRUE@am__append_11 = -I${top_srcdir}/third-party/neverbleed
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@@HAVE_NEVERBLEED_TRUE@am__append_12 = ${top_builddir}/third-party/libneverbleed.la
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@am__append_13 = nghttpx-unittest
-@ENABLE_HPACK_TOOLS_TRUE@am__append_14 = inflatehd deflatehd
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@@HAVE_NEVERBLEED_TRUE@am__append_13 = -I${top_srcdir}/third-party/neverbleed
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@@HAVE_NEVERBLEED_TRUE@am__append_14 = ${top_builddir}/third-party/libneverbleed.la
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@am__append_15 = nghttpx-unittest
+@ENABLE_HPACK_TOOLS_TRUE@am__append_16 = inflatehd deflatehd
 subdir = src
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_asio.m4 \
@@ -232,8 +245,10 @@ am__libnghttpx_a_SOURCES_DIST = util.cc util.h http2.cc http2.h \
        shrpx_api_downstream_connection.cc \
        shrpx_api_downstream_connection.h \
        shrpx_health_monitor_downstream_connection.cc \
-       shrpx_health_monitor_downstream_connection.h shrpx_exec.cc \
-       shrpx_exec.h shrpx_dns_resolver.cc shrpx_dns_resolver.h \
+       shrpx_health_monitor_downstream_connection.h \
+       shrpx_null_downstream_connection.cc \
+       shrpx_null_downstream_connection.h shrpx_exec.cc shrpx_exec.h \
+       shrpx_dns_resolver.cc shrpx_dns_resolver.h \
        shrpx_dual_dns_resolver.cc shrpx_dual_dns_resolver.h \
        shrpx_dns_tracker.cc shrpx_dns_tracker.h buffer.h memchunk.h \
        template.h allocator.h xsi_strerror.c xsi_strerror.h \
@@ -241,13 +256,23 @@ am__libnghttpx_a_SOURCES_DIST = util.cc util.h http2.cc http2.h \
        shrpx_mruby_module.h shrpx_mruby_module_env.cc \
        shrpx_mruby_module_env.h shrpx_mruby_module_request.cc \
        shrpx_mruby_module_request.h shrpx_mruby_module_response.cc \
-       shrpx_mruby_module_response.h
+       shrpx_mruby_module_response.h shrpx_quic.cc shrpx_quic.h \
+       shrpx_quic_listener.cc shrpx_quic_listener.h \
+       shrpx_quic_connection_handler.cc \
+       shrpx_quic_connection_handler.h shrpx_http3_upstream.cc \
+       shrpx_http3_upstream.h http3.cc http3.h quic.cc quic.h
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@am__objects_1 = libnghttpx_a-shrpx_mruby.$(OBJEXT) \
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@     libnghttpx_a-shrpx_mruby_module.$(OBJEXT) \
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@     libnghttpx_a-shrpx_mruby_module_env.$(OBJEXT) \
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@     libnghttpx_a-shrpx_mruby_module_request.$(OBJEXT) \
 @ENABLE_APP_TRUE@@HAVE_MRUBY_TRUE@     libnghttpx_a-shrpx_mruby_module_response.$(OBJEXT)
-@ENABLE_APP_TRUE@am__objects_2 = libnghttpx_a-util.$(OBJEXT) \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@am__objects_2 = libnghttpx_a-shrpx_quic.$(OBJEXT) \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   libnghttpx_a-shrpx_quic_listener.$(OBJEXT) \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   libnghttpx_a-shrpx_quic_connection_handler.$(OBJEXT) \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   libnghttpx_a-shrpx_http3_upstream.$(OBJEXT) \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   libnghttpx_a-http3.$(OBJEXT) \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   libnghttpx_a-quic.$(OBJEXT)
+@ENABLE_APP_TRUE@am__objects_3 = libnghttpx_a-util.$(OBJEXT) \
 @ENABLE_APP_TRUE@      libnghttpx_a-http2.$(OBJEXT) \
 @ENABLE_APP_TRUE@      libnghttpx_a-timegm.$(OBJEXT) \
 @ENABLE_APP_TRUE@      libnghttpx_a-app_helper.$(OBJEXT) \
@@ -282,13 +307,14 @@ am__libnghttpx_a_SOURCES_DIST = util.cc util.h http2.cc http2.h \
 @ENABLE_APP_TRUE@      libnghttpx_a-shrpx_router.$(OBJEXT) \
 @ENABLE_APP_TRUE@      libnghttpx_a-shrpx_api_downstream_connection.$(OBJEXT) \
 @ENABLE_APP_TRUE@      libnghttpx_a-shrpx_health_monitor_downstream_connection.$(OBJEXT) \
+@ENABLE_APP_TRUE@      libnghttpx_a-shrpx_null_downstream_connection.$(OBJEXT) \
 @ENABLE_APP_TRUE@      libnghttpx_a-shrpx_exec.$(OBJEXT) \
 @ENABLE_APP_TRUE@      libnghttpx_a-shrpx_dns_resolver.$(OBJEXT) \
 @ENABLE_APP_TRUE@      libnghttpx_a-shrpx_dual_dns_resolver.$(OBJEXT) \
 @ENABLE_APP_TRUE@      libnghttpx_a-shrpx_dns_tracker.$(OBJEXT) \
 @ENABLE_APP_TRUE@      libnghttpx_a-xsi_strerror.$(OBJEXT) \
-@ENABLE_APP_TRUE@      $(am__objects_1)
-@ENABLE_APP_TRUE@am_libnghttpx_a_OBJECTS = $(am__objects_2)
+@ENABLE_APP_TRUE@      $(am__objects_1) $(am__objects_2)
+@ENABLE_APP_TRUE@am_libnghttpx_a_OBJECTS = $(am__objects_3)
 libnghttpx_a_OBJECTS = $(am_libnghttpx_a_OBJECTS)
 am__DEPENDENCIES_1 =
 @ENABLE_ASIO_LIB_TRUE@libnghttp2_asio_la_DEPENDENCIES =  \
@@ -361,9 +387,9 @@ libnghttp2_asio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(LDFLAGS) -o $@
 @ENABLE_ASIO_LIB_TRUE@am_libnghttp2_asio_la_rpath = -rpath $(libdir)
 am__deflatehd_SOURCES_DIST = deflatehd.cc comp_helper.c comp_helper.h
-@ENABLE_HPACK_TOOLS_TRUE@am__objects_3 = comp_helper.$(OBJEXT)
+@ENABLE_HPACK_TOOLS_TRUE@am__objects_4 = comp_helper.$(OBJEXT)
 @ENABLE_HPACK_TOOLS_TRUE@am_deflatehd_OBJECTS = deflatehd.$(OBJEXT) \
-@ENABLE_HPACK_TOOLS_TRUE@      $(am__objects_3)
+@ENABLE_HPACK_TOOLS_TRUE@      $(am__objects_4)
 deflatehd_OBJECTS = $(am_deflatehd_OBJECTS)
 deflatehd_LDADD = $(LDADD)
 deflatehd_DEPENDENCIES = $(top_builddir)/lib/libnghttp2.la \
@@ -372,11 +398,17 @@ deflatehd_DEPENDENCIES = $(top_builddir)/lib/libnghttp2.la \
 am__h2load_SOURCES_DIST = util.cc util.h http2.cc http2.h h2load.cc \
        h2load.h timegm.c timegm.h tls.cc tls.h h2load_session.h \
        h2load_http2_session.cc h2load_http2_session.h \
-       h2load_http1_session.cc h2load_http1_session.h
+       h2load_http1_session.cc h2load_http1_session.h \
+       h2load_http3_session.cc h2load_http3_session.h h2load_quic.cc \
+       h2load_quic.h quic.cc quic.h
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@am__objects_5 = h2load_http3_session.$(OBJEXT) \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   h2load_quic.$(OBJEXT) \
+@ENABLE_APP_TRUE@@ENABLE_HTTP3_TRUE@   quic.$(OBJEXT)
 @ENABLE_APP_TRUE@am_h2load_OBJECTS = util.$(OBJEXT) http2.$(OBJEXT) \
 @ENABLE_APP_TRUE@      h2load.$(OBJEXT) timegm.$(OBJEXT) \
 @ENABLE_APP_TRUE@      tls.$(OBJEXT) h2load_http2_session.$(OBJEXT) \
-@ENABLE_APP_TRUE@      h2load_http1_session.$(OBJEXT)
+@ENABLE_APP_TRUE@      h2load_http1_session.$(OBJEXT) \
+@ENABLE_APP_TRUE@      $(am__objects_5)
 h2load_OBJECTS = $(am_h2load_OBJECTS)
 h2load_LDADD = $(LDADD)
 h2load_DEPENDENCIES = $(top_builddir)/lib/libnghttp2.la \
@@ -384,7 +416,7 @@ h2load_DEPENDENCIES = $(top_builddir)/lib/libnghttp2.la \
        $(top_builddir)/third-party/libllhttp.la
 am__inflatehd_SOURCES_DIST = inflatehd.cc comp_helper.c comp_helper.h
 @ENABLE_HPACK_TOOLS_TRUE@am_inflatehd_OBJECTS = inflatehd.$(OBJEXT) \
-@ENABLE_HPACK_TOOLS_TRUE@      $(am__objects_3)
+@ENABLE_HPACK_TOOLS_TRUE@      $(am__objects_4)
 inflatehd_OBJECTS = $(am_inflatehd_OBJECTS)
 inflatehd_LDADD = $(LDADD)
 inflatehd_DEPENDENCIES = $(top_builddir)/lib/libnghttp2.la \
@@ -394,16 +426,16 @@ am__nghttp_SOURCES_DIST = util.cc http2.cc timegm.c app_helper.cc \
        nghttp2_gzip.c util.h http2.h timegm.h app_helper.h \
        nghttp2_config.h nghttp2_gzip.h network.h nghttp.cc nghttp.h \
        HtmlParser.cc HtmlParser.h tls.cc tls.h
-@ENABLE_APP_TRUE@am__objects_4 = util.$(OBJEXT) http2.$(OBJEXT) \
+@ENABLE_APP_TRUE@am__objects_6 = util.$(OBJEXT) http2.$(OBJEXT) \
 @ENABLE_APP_TRUE@      timegm.$(OBJEXT) app_helper.$(OBJEXT) \
 @ENABLE_APP_TRUE@      nghttp2_gzip.$(OBJEXT)
-am__objects_5 =
-@ENABLE_APP_TRUE@@HAVE_LIBXML2_TRUE@am__objects_6 =  \
+am__objects_7 =
+@ENABLE_APP_TRUE@@HAVE_LIBXML2_TRUE@am__objects_8 =  \
 @ENABLE_APP_TRUE@@HAVE_LIBXML2_TRUE@   HtmlParser.$(OBJEXT)
-@ENABLE_APP_TRUE@am__objects_7 = $(am__objects_6)
-@ENABLE_APP_TRUE@am_nghttp_OBJECTS = $(am__objects_4) $(am__objects_5) \
-@ENABLE_APP_TRUE@      nghttp.$(OBJEXT) $(am__objects_7) \
-@ENABLE_APP_TRUE@      $(am__objects_5) tls.$(OBJEXT)
+@ENABLE_APP_TRUE@am__objects_9 = $(am__objects_8)
+@ENABLE_APP_TRUE@am_nghttp_OBJECTS = $(am__objects_6) $(am__objects_7) \
+@ENABLE_APP_TRUE@      nghttp.$(OBJEXT) $(am__objects_9) \
+@ENABLE_APP_TRUE@      $(am__objects_7) tls.$(OBJEXT)
 nghttp_OBJECTS = $(am_nghttp_OBJECTS)
 nghttp_LDADD = $(LDADD)
 nghttp_DEPENDENCIES = $(top_builddir)/lib/libnghttp2.la \
@@ -413,8 +445,8 @@ am__nghttpd_SOURCES_DIST = util.cc http2.cc timegm.c app_helper.cc \
        nghttp2_gzip.c util.h http2.h timegm.h app_helper.h \
        nghttp2_config.h nghttp2_gzip.h network.h nghttpd.cc tls.cc \
        tls.h HttpServer.cc HttpServer.h
-@ENABLE_APP_TRUE@am_nghttpd_OBJECTS = $(am__objects_4) \
-@ENABLE_APP_TRUE@      $(am__objects_5) nghttpd.$(OBJEXT) \
+@ENABLE_APP_TRUE@am_nghttpd_OBJECTS = $(am__objects_6) \
+@ENABLE_APP_TRUE@      $(am__objects_7) nghttpd.$(OBJEXT) \
 @ENABLE_APP_TRUE@      tls.$(OBJEXT) HttpServer.$(OBJEXT)
 nghttpd_OBJECTS = $(am_nghttpd_OBJECTS)
 nghttpd_LDADD = $(LDADD)
@@ -429,7 +461,7 @@ am__DEPENDENCIES_2 = $(top_builddir)/lib/libnghttp2.la \
        $(top_builddir)/third-party/libllhttp.la
 @ENABLE_APP_TRUE@nghttpx_DEPENDENCIES = libnghttpx.a \
 @ENABLE_APP_TRUE@      $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
-@ENABLE_APP_TRUE@      $(am__append_7)
+@ENABLE_APP_TRUE@      $(am__append_9)
 am__nghttpx_unittest_SOURCES_DIST = shrpx-unittest.cc \
        shrpx_tls_test.cc shrpx_tls_test.h shrpx_downstream_test.cc \
        shrpx_downstream_test.h shrpx_config_test.cc \
@@ -460,7 +492,7 @@ nghttpx_unittest_OBJECTS = $(am_nghttpx_unittest_OBJECTS)
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     libnghttpx.a \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__DEPENDENCIES_2) \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__DEPENDENCIES_1) \
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__append_12)
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__append_14)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -480,8 +512,9 @@ am__depfiles_remade = ./$(DEPDIR)/HtmlParser.Po \
        ./$(DEPDIR)/HttpServer.Po ./$(DEPDIR)/app_helper.Po \
        ./$(DEPDIR)/comp_helper.Po ./$(DEPDIR)/deflatehd.Po \
        ./$(DEPDIR)/h2load.Po ./$(DEPDIR)/h2load_http1_session.Po \
-       ./$(DEPDIR)/h2load_http2_session.Po ./$(DEPDIR)/http2.Po \
-       ./$(DEPDIR)/inflatehd.Po \
+       ./$(DEPDIR)/h2load_http2_session.Po \
+       ./$(DEPDIR)/h2load_http3_session.Po ./$(DEPDIR)/h2load_quic.Po \
+       ./$(DEPDIR)/http2.Po ./$(DEPDIR)/inflatehd.Po \
        ./$(DEPDIR)/libnghttp2_asio_la-asio_client_request.Plo \
        ./$(DEPDIR)/libnghttp2_asio_la-asio_client_request_impl.Plo \
        ./$(DEPDIR)/libnghttp2_asio_la-asio_client_response.Plo \
@@ -512,6 +545,8 @@ am__depfiles_remade = ./$(DEPDIR)/HtmlParser.Po \
        ./$(DEPDIR)/libnghttp2_asio_la-util.Plo \
        ./$(DEPDIR)/libnghttpx_a-app_helper.Po \
        ./$(DEPDIR)/libnghttpx_a-http2.Po \
+       ./$(DEPDIR)/libnghttpx_a-http3.Po \
+       ./$(DEPDIR)/libnghttpx_a-quic.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_accept_handler.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_api_downstream_connection.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_client_handler.Po \
@@ -532,6 +567,7 @@ am__depfiles_remade = ./$(DEPDIR)/HtmlParser.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_http2_downstream_connection.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_http2_session.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_http2_upstream.Po \
+       ./$(DEPDIR)/libnghttpx_a-shrpx_http3_upstream.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_http_downstream_connection.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_https_upstream.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_io_control.Po \
@@ -545,6 +581,10 @@ am__depfiles_remade = ./$(DEPDIR)/HtmlParser.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_env.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_request.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_response.Po \
+       ./$(DEPDIR)/libnghttpx_a-shrpx_null_downstream_connection.Po \
+       ./$(DEPDIR)/libnghttpx_a-shrpx_quic.Po \
+       ./$(DEPDIR)/libnghttpx_a-shrpx_quic_connection_handler.Po \
+       ./$(DEPDIR)/libnghttpx_a-shrpx_quic_listener.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_rate_limit.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_router.Po \
        ./$(DEPDIR)/libnghttpx_a-shrpx_signal.Po \
@@ -571,7 +611,7 @@ am__depfiles_remade = ./$(DEPDIR)/HtmlParser.Po \
        ./$(DEPDIR)/nghttpx_unittest-shrpx_tls_test.Po \
        ./$(DEPDIR)/nghttpx_unittest-shrpx_worker_test.Po \
        ./$(DEPDIR)/nghttpx_unittest-template_test.Po \
-       ./$(DEPDIR)/nghttpx_unittest-util_test.Po \
+       ./$(DEPDIR)/nghttpx_unittest-util_test.Po ./$(DEPDIR)/quic.Po \
        ./$(DEPDIR)/timegm.Po ./$(DEPDIR)/tls.Po ./$(DEPDIR)/util.Po
 am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -659,8 +699,6 @@ am__define_uniq_tagged_files = \
   unique=`for i in $$list; do \
     if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
   done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
 am__tty_colors_dummy = \
   mgn= red= grn= lgn= blu= brg= std=; \
   am__color_tests=no
@@ -816,6 +854,7 @@ am__set_TESTS_bases = \
   bases='$(TEST_LOGS)'; \
   bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
   bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
 RECHECK_LOGS = $(TEST_LOGS)
 TEST_SUITE_LOG = test-suite.log
 TEST_EXTENSIONS = @EXEEXT@ .test
@@ -881,11 +920,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -904,8 +946,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -916,9 +961,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -927,9 +975,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -967,8 +1024,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -1065,30 +1123,44 @@ AM_CFLAGS = $(WARNCFLAGS)
 AM_CXXFLAGS = $(WARNCXXFLAGS) $(CXX1XCXXFLAGS)
 AM_CPPFLAGS = \
        -DPKGDATADIR='"$(pkgdatadir)"' \
+       -DPKGLIBDIR='"$(pkglibdir)"' \
        -I$(top_srcdir)/lib/includes \
        -I$(top_builddir)/lib/includes \
        -I$(top_srcdir)/lib \
        -I$(top_srcdir)/src/includes \
        -I$(top_srcdir)/third-party \
        -I$(top_srcdir)/third-party/llhttp/include \
+       @JEMALLOC_CFLAGS@ \
        @LIBXML2_CFLAGS@ \
        @LIBEV_CFLAGS@ \
+       @LIBNGHTTP3_CFLAGS@ \
+       @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@ \
+       @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@ \
+       @LIBNGTCP2_CFLAGS@ \
        @OPENSSL_CFLAGS@ \
        @LIBCARES_CFLAGS@ \
        @JANSSON_CFLAGS@ \
+       @LIBBPF_CFLAGS@ \
        @ZLIB_CFLAGS@ \
+       @EXTRA_DEFS@ \
        @DEFS@
 
+AM_LDFLAGS = @LIBTOOL_LDFLAGS@
 LDADD = $(top_builddir)/lib/libnghttp2.la \
        $(top_builddir)/third-party/liburl-parser.la \
        $(top_builddir)/third-party/libllhttp.la \
        @JEMALLOC_LIBS@ \
        @LIBXML2_LIBS@ \
        @LIBEV_LIBS@ \
+       @LIBNGHTTP3_LIBS@ \
+       @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@ \
+       @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@ \
+       @LIBNGTCP2_LIBS@ \
        @OPENSSL_LIBS@ \
        @LIBCARES_LIBS@ \
        @SYSTEMD_LIBS@ \
        @JANSSON_LIBS@ \
+       @LIBBPF_LIBS@ \
        @ZLIB_LIBS@ \
        @APPLDFLAGS@
 
@@ -1109,14 +1181,13 @@ LDADD = $(top_builddir)/lib/libnghttp2.la \
 @ENABLE_APP_TRUE@      tls.cc tls.h \
 @ENABLE_APP_TRUE@      HttpServer.cc HttpServer.h
 
-@ENABLE_APP_TRUE@h2load_SOURCES = util.cc util.h \
-@ENABLE_APP_TRUE@      http2.cc http2.h h2load.cc h2load.h \
-@ENABLE_APP_TRUE@      timegm.c timegm.h \
-@ENABLE_APP_TRUE@      tls.cc tls.h \
-@ENABLE_APP_TRUE@      h2load_session.h \
-@ENABLE_APP_TRUE@      h2load_http2_session.cc h2load_http2_session.h \
-@ENABLE_APP_TRUE@      h2load_http1_session.cc h2load_http1_session.h
-
+@ENABLE_APP_TRUE@h2load_SOURCES = util.cc util.h http2.cc http2.h \
+@ENABLE_APP_TRUE@      h2load.cc h2load.h timegm.c timegm.h tls.cc \
+@ENABLE_APP_TRUE@      tls.h h2load_session.h \
+@ENABLE_APP_TRUE@      h2load_http2_session.cc \
+@ENABLE_APP_TRUE@      h2load_http2_session.h \
+@ENABLE_APP_TRUE@      h2load_http1_session.cc \
+@ENABLE_APP_TRUE@      h2load_http1_session.h $(am__append_3)
 @ENABLE_APP_TRUE@NGHTTPX_SRCS = util.cc util.h http2.cc http2.h \
 @ENABLE_APP_TRUE@      timegm.c timegm.h base64.h app_helper.cc \
 @ENABLE_APP_TRUE@      app_helper.h tls.cc tls.h shrpx_config.cc \
@@ -1166,21 +1237,24 @@ LDADD = $(top_builddir)/lib/libnghttp2.la \
 @ENABLE_APP_TRUE@      shrpx_api_downstream_connection.h \
 @ENABLE_APP_TRUE@      shrpx_health_monitor_downstream_connection.cc \
 @ENABLE_APP_TRUE@      shrpx_health_monitor_downstream_connection.h \
+@ENABLE_APP_TRUE@      shrpx_null_downstream_connection.cc \
+@ENABLE_APP_TRUE@      shrpx_null_downstream_connection.h \
 @ENABLE_APP_TRUE@      shrpx_exec.cc shrpx_exec.h \
 @ENABLE_APP_TRUE@      shrpx_dns_resolver.cc shrpx_dns_resolver.h \
 @ENABLE_APP_TRUE@      shrpx_dual_dns_resolver.cc \
 @ENABLE_APP_TRUE@      shrpx_dual_dns_resolver.h \
 @ENABLE_APP_TRUE@      shrpx_dns_tracker.cc shrpx_dns_tracker.h \
 @ENABLE_APP_TRUE@      buffer.h memchunk.h template.h allocator.h \
-@ENABLE_APP_TRUE@      xsi_strerror.c xsi_strerror.h $(am__append_3)
+@ENABLE_APP_TRUE@      xsi_strerror.c xsi_strerror.h $(am__append_4) \
+@ENABLE_APP_TRUE@      $(am__append_5)
 @ENABLE_APP_TRUE@noinst_LIBRARIES = libnghttpx.a
 @ENABLE_APP_TRUE@libnghttpx_a_SOURCES = ${NGHTTPX_SRCS}
 @ENABLE_APP_TRUE@libnghttpx_a_CPPFLAGS = ${AM_CPPFLAGS} \
-@ENABLE_APP_TRUE@      $(am__append_4) $(am__append_6)
+@ENABLE_APP_TRUE@      $(am__append_6) $(am__append_8)
 @ENABLE_APP_TRUE@nghttpx_SOURCES = shrpx.cc shrpx.h
 @ENABLE_APP_TRUE@nghttpx_CPPFLAGS = ${libnghttpx_a_CPPFLAGS}
-@ENABLE_APP_TRUE@nghttpx_LDADD = libnghttpx.a ${LDADD} $(am__append_5) \
-@ENABLE_APP_TRUE@      $(am__append_7)
+@ENABLE_APP_TRUE@nghttpx_LDADD = libnghttpx.a ${LDADD} $(am__append_7) \
+@ENABLE_APP_TRUE@      $(am__append_9)
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@nghttpx_unittest_SOURCES = shrpx-unittest.cc \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     shrpx_tls_test.cc shrpx_tls_test.h \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     shrpx_downstream_test.cc shrpx_downstream_test.h \
@@ -1200,13 +1274,13 @@ LDADD = $(top_builddir)/lib/libnghttp2.la \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@nghttpx_unittest_CPPFLAGS =  \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     ${AM_CPPFLAGS} \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     -DNGHTTP2_SRC_DIR=\"$(top_srcdir)/src\" \
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__append_9) \
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__append_11)
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__append_11) \
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__append_13)
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@nghttpx_unittest_LDADD =  \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     libnghttpx.a ${LDADD} \
 @ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     @CUNIT_LIBS@ @TESTLDADD@ \
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__append_10) \
-@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__append_12)
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__append_12) \
+@ENABLE_APP_TRUE@@HAVE_CUNIT_TRUE@     $(am__append_14)
 @ENABLE_HPACK_TOOLS_TRUE@HPACK_TOOLS_COMMON_SRCS = comp_helper.c comp_helper.h
 @ENABLE_HPACK_TOOLS_TRUE@inflatehd_SOURCES = inflatehd.cc $(HPACK_TOOLS_COMMON_SRCS)
 @ENABLE_HPACK_TOOLS_TRUE@deflatehd_SOURCES = deflatehd.cc $(HPACK_TOOLS_COMMON_SRCS)
@@ -1246,7 +1320,7 @@ LDADD = $(top_builddir)/lib/libnghttp2.la \
 @ENABLE_ASIO_LIB_TRUE@ asio_client_tls_context.cc asio_client_tls_context.h
 
 @ENABLE_ASIO_LIB_TRUE@libnghttp2_asio_la_CPPFLAGS = ${AM_CPPFLAGS} ${BOOST_CPPFLAGS}
-@ENABLE_ASIO_LIB_TRUE@libnghttp2_asio_la_LDFLAGS = -no-undefined -version-info 1:0:0
+@ENABLE_ASIO_LIB_TRUE@libnghttp2_asio_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 1:0:0
 @ENABLE_ASIO_LIB_TRUE@libnghttp2_asio_la_LIBADD = \
 @ENABLE_ASIO_LIB_TRUE@ $(top_builddir)/lib/libnghttp2.la \
 @ENABLE_ASIO_LIB_TRUE@ $(top_builddir)/third-party/liburl-parser.la \
@@ -1439,6 +1513,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h2load.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h2load_http1_session.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h2load_http2_session.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h2load_http3_session.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h2load_quic.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http2.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inflatehd.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttp2_asio_la-asio_client_request.Plo@am__quote@ # am--include-marker
@@ -1471,6 +1547,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttp2_asio_la-util.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-app_helper.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-http2.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-http3.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-quic.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_accept_handler.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_api_downstream_connection.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_client_handler.Po@am__quote@ # am--include-marker
@@ -1491,6 +1569,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_http2_downstream_connection.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_http2_session.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_http2_upstream.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_http3_upstream.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_http_downstream_connection.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_https_upstream.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_io_control.Po@am__quote@ # am--include-marker
@@ -1504,6 +1583,10 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_env.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_request.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_response.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_null_downstream_connection.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_quic.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_quic_connection_handler.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_quic_listener.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_rate_limit.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_router.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnghttpx_a-shrpx_signal.Po@am__quote@ # am--include-marker
@@ -1533,6 +1616,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttpx_unittest-shrpx_worker_test.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttpx_unittest-template_test.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttpx_unittest-util_test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quic.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timegm.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ # am--include-marker
@@ -2130,6 +2214,20 @@ libnghttpx_a-shrpx_health_monitor_downstream_connection.obj: shrpx_health_monito
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_health_monitor_downstream_connection.obj `if test -f 'shrpx_health_monitor_downstream_connection.cc'; then $(CYGPATH_W) 'shrpx_health_monitor_downstream_connection.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_health_monitor_downstream_connection.cc'; fi`
 
+libnghttpx_a-shrpx_null_downstream_connection.o: shrpx_null_downstream_connection.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_null_downstream_connection.o -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_null_downstream_connection.Tpo -c -o libnghttpx_a-shrpx_null_downstream_connection.o `test -f 'shrpx_null_downstream_connection.cc' || echo '$(srcdir)/'`shrpx_null_downstream_connection.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_null_downstream_connection.Tpo $(DEPDIR)/libnghttpx_a-shrpx_null_downstream_connection.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='shrpx_null_downstream_connection.cc' object='libnghttpx_a-shrpx_null_downstream_connection.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_null_downstream_connection.o `test -f 'shrpx_null_downstream_connection.cc' || echo '$(srcdir)/'`shrpx_null_downstream_connection.cc
+
+libnghttpx_a-shrpx_null_downstream_connection.obj: shrpx_null_downstream_connection.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_null_downstream_connection.obj -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_null_downstream_connection.Tpo -c -o libnghttpx_a-shrpx_null_downstream_connection.obj `if test -f 'shrpx_null_downstream_connection.cc'; then $(CYGPATH_W) 'shrpx_null_downstream_connection.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_null_downstream_connection.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_null_downstream_connection.Tpo $(DEPDIR)/libnghttpx_a-shrpx_null_downstream_connection.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='shrpx_null_downstream_connection.cc' object='libnghttpx_a-shrpx_null_downstream_connection.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_null_downstream_connection.obj `if test -f 'shrpx_null_downstream_connection.cc'; then $(CYGPATH_W) 'shrpx_null_downstream_connection.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_null_downstream_connection.cc'; fi`
+
 libnghttpx_a-shrpx_exec.o: shrpx_exec.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_exec.o -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_exec.Tpo -c -o libnghttpx_a-shrpx_exec.o `test -f 'shrpx_exec.cc' || echo '$(srcdir)/'`shrpx_exec.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_exec.Tpo $(DEPDIR)/libnghttpx_a-shrpx_exec.Po
@@ -2256,6 +2354,90 @@ libnghttpx_a-shrpx_mruby_module_response.obj: shrpx_mruby_module_response.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_mruby_module_response.obj `if test -f 'shrpx_mruby_module_response.cc'; then $(CYGPATH_W) 'shrpx_mruby_module_response.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_mruby_module_response.cc'; fi`
 
+libnghttpx_a-shrpx_quic.o: shrpx_quic.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_quic.o -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_quic.Tpo -c -o libnghttpx_a-shrpx_quic.o `test -f 'shrpx_quic.cc' || echo '$(srcdir)/'`shrpx_quic.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_quic.Tpo $(DEPDIR)/libnghttpx_a-shrpx_quic.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='shrpx_quic.cc' object='libnghttpx_a-shrpx_quic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_quic.o `test -f 'shrpx_quic.cc' || echo '$(srcdir)/'`shrpx_quic.cc
+
+libnghttpx_a-shrpx_quic.obj: shrpx_quic.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_quic.obj -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_quic.Tpo -c -o libnghttpx_a-shrpx_quic.obj `if test -f 'shrpx_quic.cc'; then $(CYGPATH_W) 'shrpx_quic.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_quic.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_quic.Tpo $(DEPDIR)/libnghttpx_a-shrpx_quic.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='shrpx_quic.cc' object='libnghttpx_a-shrpx_quic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_quic.obj `if test -f 'shrpx_quic.cc'; then $(CYGPATH_W) 'shrpx_quic.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_quic.cc'; fi`
+
+libnghttpx_a-shrpx_quic_listener.o: shrpx_quic_listener.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_quic_listener.o -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_quic_listener.Tpo -c -o libnghttpx_a-shrpx_quic_listener.o `test -f 'shrpx_quic_listener.cc' || echo '$(srcdir)/'`shrpx_quic_listener.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_quic_listener.Tpo $(DEPDIR)/libnghttpx_a-shrpx_quic_listener.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='shrpx_quic_listener.cc' object='libnghttpx_a-shrpx_quic_listener.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_quic_listener.o `test -f 'shrpx_quic_listener.cc' || echo '$(srcdir)/'`shrpx_quic_listener.cc
+
+libnghttpx_a-shrpx_quic_listener.obj: shrpx_quic_listener.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_quic_listener.obj -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_quic_listener.Tpo -c -o libnghttpx_a-shrpx_quic_listener.obj `if test -f 'shrpx_quic_listener.cc'; then $(CYGPATH_W) 'shrpx_quic_listener.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_quic_listener.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_quic_listener.Tpo $(DEPDIR)/libnghttpx_a-shrpx_quic_listener.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='shrpx_quic_listener.cc' object='libnghttpx_a-shrpx_quic_listener.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_quic_listener.obj `if test -f 'shrpx_quic_listener.cc'; then $(CYGPATH_W) 'shrpx_quic_listener.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_quic_listener.cc'; fi`
+
+libnghttpx_a-shrpx_quic_connection_handler.o: shrpx_quic_connection_handler.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_quic_connection_handler.o -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_quic_connection_handler.Tpo -c -o libnghttpx_a-shrpx_quic_connection_handler.o `test -f 'shrpx_quic_connection_handler.cc' || echo '$(srcdir)/'`shrpx_quic_connection_handler.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_quic_connection_handler.Tpo $(DEPDIR)/libnghttpx_a-shrpx_quic_connection_handler.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='shrpx_quic_connection_handler.cc' object='libnghttpx_a-shrpx_quic_connection_handler.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_quic_connection_handler.o `test -f 'shrpx_quic_connection_handler.cc' || echo '$(srcdir)/'`shrpx_quic_connection_handler.cc
+
+libnghttpx_a-shrpx_quic_connection_handler.obj: shrpx_quic_connection_handler.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_quic_connection_handler.obj -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_quic_connection_handler.Tpo -c -o libnghttpx_a-shrpx_quic_connection_handler.obj `if test -f 'shrpx_quic_connection_handler.cc'; then $(CYGPATH_W) 'shrpx_quic_connection_handler.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_quic_connection_handler.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_quic_connection_handler.Tpo $(DEPDIR)/libnghttpx_a-shrpx_quic_connection_handler.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='shrpx_quic_connection_handler.cc' object='libnghttpx_a-shrpx_quic_connection_handler.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_quic_connection_handler.obj `if test -f 'shrpx_quic_connection_handler.cc'; then $(CYGPATH_W) 'shrpx_quic_connection_handler.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_quic_connection_handler.cc'; fi`
+
+libnghttpx_a-shrpx_http3_upstream.o: shrpx_http3_upstream.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_http3_upstream.o -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_http3_upstream.Tpo -c -o libnghttpx_a-shrpx_http3_upstream.o `test -f 'shrpx_http3_upstream.cc' || echo '$(srcdir)/'`shrpx_http3_upstream.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_http3_upstream.Tpo $(DEPDIR)/libnghttpx_a-shrpx_http3_upstream.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='shrpx_http3_upstream.cc' object='libnghttpx_a-shrpx_http3_upstream.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_http3_upstream.o `test -f 'shrpx_http3_upstream.cc' || echo '$(srcdir)/'`shrpx_http3_upstream.cc
+
+libnghttpx_a-shrpx_http3_upstream.obj: shrpx_http3_upstream.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-shrpx_http3_upstream.obj -MD -MP -MF $(DEPDIR)/libnghttpx_a-shrpx_http3_upstream.Tpo -c -o libnghttpx_a-shrpx_http3_upstream.obj `if test -f 'shrpx_http3_upstream.cc'; then $(CYGPATH_W) 'shrpx_http3_upstream.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_http3_upstream.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-shrpx_http3_upstream.Tpo $(DEPDIR)/libnghttpx_a-shrpx_http3_upstream.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='shrpx_http3_upstream.cc' object='libnghttpx_a-shrpx_http3_upstream.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-shrpx_http3_upstream.obj `if test -f 'shrpx_http3_upstream.cc'; then $(CYGPATH_W) 'shrpx_http3_upstream.cc'; else $(CYGPATH_W) '$(srcdir)/shrpx_http3_upstream.cc'; fi`
+
+libnghttpx_a-http3.o: http3.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-http3.o -MD -MP -MF $(DEPDIR)/libnghttpx_a-http3.Tpo -c -o libnghttpx_a-http3.o `test -f 'http3.cc' || echo '$(srcdir)/'`http3.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-http3.Tpo $(DEPDIR)/libnghttpx_a-http3.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='http3.cc' object='libnghttpx_a-http3.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-http3.o `test -f 'http3.cc' || echo '$(srcdir)/'`http3.cc
+
+libnghttpx_a-http3.obj: http3.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-http3.obj -MD -MP -MF $(DEPDIR)/libnghttpx_a-http3.Tpo -c -o libnghttpx_a-http3.obj `if test -f 'http3.cc'; then $(CYGPATH_W) 'http3.cc'; else $(CYGPATH_W) '$(srcdir)/http3.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-http3.Tpo $(DEPDIR)/libnghttpx_a-http3.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='http3.cc' object='libnghttpx_a-http3.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-http3.obj `if test -f 'http3.cc'; then $(CYGPATH_W) 'http3.cc'; else $(CYGPATH_W) '$(srcdir)/http3.cc'; fi`
+
+libnghttpx_a-quic.o: quic.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-quic.o -MD -MP -MF $(DEPDIR)/libnghttpx_a-quic.Tpo -c -o libnghttpx_a-quic.o `test -f 'quic.cc' || echo '$(srcdir)/'`quic.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-quic.Tpo $(DEPDIR)/libnghttpx_a-quic.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='quic.cc' object='libnghttpx_a-quic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-quic.o `test -f 'quic.cc' || echo '$(srcdir)/'`quic.cc
+
+libnghttpx_a-quic.obj: quic.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttpx_a-quic.obj -MD -MP -MF $(DEPDIR)/libnghttpx_a-quic.Tpo -c -o libnghttpx_a-quic.obj `if test -f 'quic.cc'; then $(CYGPATH_W) 'quic.cc'; else $(CYGPATH_W) '$(srcdir)/quic.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttpx_a-quic.Tpo $(DEPDIR)/libnghttpx_a-quic.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='quic.cc' object='libnghttpx_a-quic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttpx_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libnghttpx_a-quic.obj `if test -f 'quic.cc'; then $(CYGPATH_W) 'quic.cc'; else $(CYGPATH_W) '$(srcdir)/quic.cc'; fi`
+
 libnghttp2_asio_la-util.lo: util.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnghttp2_asio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libnghttp2_asio_la-util.lo -MD -MP -MF $(DEPDIR)/libnghttp2_asio_la-util.Tpo -c -o libnghttp2_asio_la-util.lo `test -f 'util.cc' || echo '$(srcdir)/'`util.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libnghttp2_asio_la-util.Tpo $(DEPDIR)/libnghttp2_asio_la-util.Plo
@@ -2874,7 +3056,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
          test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);               \
        fi;                                                             \
        echo "$${col}$$br$${std}";                                      \
-       echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";   \
+       echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
        echo "$${col}$$br$${std}";                                      \
        create_testsuite_report --maybe-color;                          \
        echo "$$col$$br$$std";                                          \
@@ -2929,7 +3111,6 @@ nghttpx-unittest.log: nghttpx-unittest$(EXEEXT)
 @am__EXEEXT_TRUE@      --log-file $$b.log --trs-file $$b.trs \
 @am__EXEEXT_TRUE@      $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
 @am__EXEEXT_TRUE@      "$$tst" $(AM_TESTS_FD_REDIRECT)
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -3049,6 +3230,8 @@ distclean: distclean-recursive
        -rm -f ./$(DEPDIR)/h2load.Po
        -rm -f ./$(DEPDIR)/h2load_http1_session.Po
        -rm -f ./$(DEPDIR)/h2load_http2_session.Po
+       -rm -f ./$(DEPDIR)/h2load_http3_session.Po
+       -rm -f ./$(DEPDIR)/h2load_quic.Po
        -rm -f ./$(DEPDIR)/http2.Po
        -rm -f ./$(DEPDIR)/inflatehd.Po
        -rm -f ./$(DEPDIR)/libnghttp2_asio_la-asio_client_request.Plo
@@ -3081,6 +3264,8 @@ distclean: distclean-recursive
        -rm -f ./$(DEPDIR)/libnghttp2_asio_la-util.Plo
        -rm -f ./$(DEPDIR)/libnghttpx_a-app_helper.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-http2.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-http3.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-quic.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_accept_handler.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_api_downstream_connection.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_client_handler.Po
@@ -3101,6 +3286,7 @@ distclean: distclean-recursive
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_http2_downstream_connection.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_http2_session.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_http2_upstream.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_http3_upstream.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_http_downstream_connection.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_https_upstream.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_io_control.Po
@@ -3114,6 +3300,10 @@ distclean: distclean-recursive
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_env.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_request.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_response.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_null_downstream_connection.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_quic.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_quic_connection_handler.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_quic_listener.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_rate_limit.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_router.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_signal.Po
@@ -3143,6 +3333,7 @@ distclean: distclean-recursive
        -rm -f ./$(DEPDIR)/nghttpx_unittest-shrpx_worker_test.Po
        -rm -f ./$(DEPDIR)/nghttpx_unittest-template_test.Po
        -rm -f ./$(DEPDIR)/nghttpx_unittest-util_test.Po
+       -rm -f ./$(DEPDIR)/quic.Po
        -rm -f ./$(DEPDIR)/timegm.Po
        -rm -f ./$(DEPDIR)/tls.Po
        -rm -f ./$(DEPDIR)/util.Po
@@ -3199,6 +3390,8 @@ maintainer-clean: maintainer-clean-recursive
        -rm -f ./$(DEPDIR)/h2load.Po
        -rm -f ./$(DEPDIR)/h2load_http1_session.Po
        -rm -f ./$(DEPDIR)/h2load_http2_session.Po
+       -rm -f ./$(DEPDIR)/h2load_http3_session.Po
+       -rm -f ./$(DEPDIR)/h2load_quic.Po
        -rm -f ./$(DEPDIR)/http2.Po
        -rm -f ./$(DEPDIR)/inflatehd.Po
        -rm -f ./$(DEPDIR)/libnghttp2_asio_la-asio_client_request.Plo
@@ -3231,6 +3424,8 @@ maintainer-clean: maintainer-clean-recursive
        -rm -f ./$(DEPDIR)/libnghttp2_asio_la-util.Plo
        -rm -f ./$(DEPDIR)/libnghttpx_a-app_helper.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-http2.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-http3.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-quic.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_accept_handler.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_api_downstream_connection.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_client_handler.Po
@@ -3251,6 +3446,7 @@ maintainer-clean: maintainer-clean-recursive
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_http2_downstream_connection.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_http2_session.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_http2_upstream.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_http3_upstream.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_http_downstream_connection.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_https_upstream.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_io_control.Po
@@ -3264,6 +3460,10 @@ maintainer-clean: maintainer-clean-recursive
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_env.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_request.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_mruby_module_response.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_null_downstream_connection.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_quic.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_quic_connection_handler.Po
+       -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_quic_listener.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_rate_limit.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_router.Po
        -rm -f ./$(DEPDIR)/libnghttpx_a-shrpx_signal.Po
@@ -3293,6 +3493,7 @@ maintainer-clean: maintainer-clean-recursive
        -rm -f ./$(DEPDIR)/nghttpx_unittest-shrpx_worker_test.Po
        -rm -f ./$(DEPDIR)/nghttpx_unittest-template_test.Po
        -rm -f ./$(DEPDIR)/nghttpx_unittest-util_test.Po
+       -rm -f ./$(DEPDIR)/quic.Po
        -rm -f ./$(DEPDIR)/timegm.Po
        -rm -f ./$(DEPDIR)/tls.Po
        -rm -f ./$(DEPDIR)/util.Po
index 6ad8352..89250d4 100644 (file)
@@ -197,7 +197,7 @@ inline size_t concat_string_ref_count(size_t acc) { return acc; }
 // accumulated, and passed to the next function.
 template <typename... Args>
 size_t concat_string_ref_count(size_t acc, const StringRef &value,
-                               Args &&... args) {
+                               Args &&...args) {
   return concat_string_ref_count(acc + value.size(),
                                  std::forward<Args>(args)...);
 }
@@ -212,7 +212,7 @@ inline uint8_t *concat_string_ref_copy(uint8_t *p) { return p; }
 // beyond the last byte written.
 template <typename... Args>
 uint8_t *concat_string_ref_copy(uint8_t *p, const StringRef &value,
-                                Args &&... args) {
+                                Args &&...args) {
   p = std::copy(std::begin(value), std::end(value), p);
   return concat_string_ref_copy(p, std::forward<Args>(args)...);
 }
@@ -220,7 +220,7 @@ uint8_t *concat_string_ref_copy(uint8_t *p, const StringRef &value,
 // Returns the string which is the concatenation of |args| in the
 // given order.  The resulting string will be NULL-terminated.
 template <typename BlockAllocator, typename... Args>
-StringRef concat_string_ref(BlockAllocator &alloc, Args &&... args) {
+StringRef concat_string_ref(BlockAllocator &alloc, Args &&...args) {
   size_t len = concat_string_ref_count(0, std::forward<Args>(args)...);
   auto dst = static_cast<uint8_t *>(alloc.alloc(len + 1));
   auto p = dst;
@@ -237,7 +237,7 @@ StringRef concat_string_ref(BlockAllocator &alloc, Args &&... args) {
 // then just call concat_string_ref().
 template <typename BlockAllocator, typename... Args>
 StringRef realloc_concat_string_ref(BlockAllocator &alloc,
-                                    const StringRef &value, Args &&... args) {
+                                    const StringRef &value, Args &&...args) {
   if (value.empty()) {
     return concat_string_ref(alloc, std::forward<Args>(args)...);
   }
index 90762d3..428dbd6 100644 (file)
@@ -97,7 +97,7 @@ generator_cb deferred_generator() {
 }
 
 template <typename F, typename... T>
-std::shared_ptr<Defer<F, T...>> defer_shared(F &&f, T &&... t) {
+std::shared_ptr<Defer<F, T...>> defer_shared(F &&f, T &&...t) {
   return std::make_shared<Defer<F, T...>>(std::forward<F>(f),
                                           std::forward<T>(t)...);
 }
index daf9a66..a948965 100644 (file)
@@ -75,7 +75,7 @@ public:
       serve_mux &mux,
       const boost::posix_time::time_duration &tls_handshake_timeout,
       const boost::posix_time::time_duration &read_timeout,
-      SocketArgs &&... args)
+      SocketArgs &&...args)
       : socket_(std::forward<SocketArgs>(args)...),
         mux_(mux),
         deadline_(GET_IO_SERVICE(socket_)),
index 2f08cac..46962cd 100644 (file)
@@ -34,6 +34,8 @@
 #ifdef HAVE_FCNTL_H
 #  include <fcntl.h>
 #endif // HAVE_FCNTL_H
+#include <sys/mman.h>
+#include <netinet/udp.h>
 
 #include <cstdio>
 #include <cassert>
 
 #include <openssl/err.h>
 
+#ifdef ENABLE_HTTP3
+#  include <ngtcp2/ngtcp2.h>
+#endif // ENABLE_HTTP3
+
 #include "url-parser/url_parser.h"
 
 #include "h2load_http1_session.h"
 #include "h2load_http2_session.h"
+#ifdef ENABLE_HTTP3
+#  include "h2load_http3_session.h"
+#  include "h2load_quic.h"
+#endif // ENABLE_HTTP3
 #include "tls.h"
 #include "http2.h"
 #include "util.h"
@@ -71,9 +81,24 @@ bool recorded(const std::chrono::steady_clock::time_point &t) {
 }
 } // namespace
 
+#if OPENSSL_1_1_1_API
+namespace {
+std::ofstream keylog_file;
+void keylog_callback(const SSL *ssl, const char *line) {
+  keylog_file.write(line, strlen(line));
+  keylog_file.put('\n');
+  keylog_file.flush();
+}
+} // namespace
+#endif // OPENSSL_1_1_1_API
+
 Config::Config()
     : ciphers(tls::DEFAULT_CIPHER_LIST),
+      tls13_ciphers("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_"
+                    "CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256"),
+      groups("X25519:P-256:P-384:P-521"),
       data_length(-1),
+      data(nullptr),
       addrs(nullptr),
       nreqs(1),
       nclients(1),
@@ -92,13 +117,17 @@ Config::Config()
       encoder_header_table_size(4_k),
       data_fd(-1),
       log_fd(-1),
+      qlog_file_base(),
       port(0),
       default_port(0),
       connect_to_port(0),
       verbose(false),
       timing_script(false),
       base_uri_unix(false),
-      unix_addr{} {}
+      unix_addr{},
+      rps(0.),
+      no_udp_gso(false),
+      max_udp_payload_size(0) {}
 
 Config::~Config() {
   if (addrs) {
@@ -117,6 +146,15 @@ Config::~Config() {
 bool Config::is_rate_mode() const { return (this->rate != 0); }
 bool Config::is_timing_based_mode() const { return (this->duration > 0); }
 bool Config::has_base_uri() const { return (!this->base_uri.empty()); }
+bool Config::rps_enabled() const { return this->rps > 0.0; }
+bool Config::is_quic() const {
+#ifdef ENABLE_HTTP3
+  return !npn_list.empty() &&
+         (npn_list[0] == NGHTTP3_ALPN_H3 || npn_list[0] == "\x5h3-29");
+#else  // !ENABLE_HTTP3
+  return false;
+#endif // !ENABLE_HTTP3
+}
 Config config;
 
 namespace {
@@ -136,7 +174,9 @@ Stats::Stats(size_t req_todo, size_t nclients)
       bytes_head(0),
       bytes_head_decomp(0),
       bytes_body(0),
-      status() {}
+      status(),
+      udp_dgram_recv(0),
+      udp_dgram_sent(0) {}
 
 Stream::Stream() : req_stat{}, status_success(-1) {}
 
@@ -193,8 +233,7 @@ void readcb(struct ev_loop *loop, ev_io *w, int revents) {
     delete client;
     return;
   }
-  writecb(loop, &client->wev, revents);
-  // client->disconnect() and client->fail() may be called
+  client->signal_write();
 }
 } // namespace
 
@@ -287,6 +326,51 @@ void warmup_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
 } // namespace
 
 namespace {
+void rps_cb(struct ev_loop *loop, ev_timer *w, int revents) {
+  auto client = static_cast<Client *>(w->data);
+  auto &session = client->session;
+
+  assert(!config.timing_script);
+
+  if (client->req_left == 0) {
+    ev_timer_stop(loop, w);
+    return;
+  }
+
+  auto now = ev_now(loop);
+  auto d = now - client->rps_duration_started;
+  auto n = static_cast<size_t>(round(d * config.rps));
+  client->rps_req_pending += n;
+  client->rps_duration_started = now - d + static_cast<double>(n) / config.rps;
+
+  if (client->rps_req_pending == 0) {
+    return;
+  }
+
+  auto nreq = session->max_concurrent_streams() - client->rps_req_inflight;
+  if (nreq == 0) {
+    return;
+  }
+
+  nreq = config.is_timing_based_mode() ? std::max(nreq, client->req_left)
+                                       : std::min(nreq, client->req_left);
+  nreq = std::min(nreq, client->rps_req_pending);
+
+  client->rps_req_inflight += nreq;
+  client->rps_req_pending -= nreq;
+
+  for (; nreq > 0; --nreq) {
+    if (client->submit_request() != 0) {
+      client->process_request_failure();
+      break;
+    }
+  }
+
+  client->signal_write();
+}
+} // namespace
+
+namespace {
 // Called when an a connection has been inactive for a set period of time
 // or a fixed amount of time after all requests have been made on a
 // connection
@@ -362,6 +446,9 @@ Client::Client(uint32_t id, Worker *worker, size_t req_todo)
       cstat{},
       worker(worker),
       ssl(nullptr),
+#ifdef ENABLE_HTTP3
+      quic{},
+#endif // ENABLE_HTTP3
       next_addr(config.addrs),
       current_addr(nullptr),
       reqidx(0),
@@ -373,8 +460,12 @@ Client::Client(uint32_t id, Worker *worker, size_t req_todo)
       req_done(0),
       id(id),
       fd(-1),
+      local_addr{},
       new_connection_requested(false),
-      final(false) {
+      final(false),
+      rps_duration_started(0),
+      rps_req_pending(0),
+      rps_req_inflight(0) {
   if (req_todo == 0) { // this means infinite number of requests are to be made
     // This ensures that number of requests are unbounded
     // Just a positive number is fine, we chose the first positive number
@@ -396,11 +487,25 @@ Client::Client(uint32_t id, Worker *worker, size_t req_todo)
 
   ev_timer_init(&request_timeout_watcher, client_request_timeout_cb, 0., 0.);
   request_timeout_watcher.data = this;
+
+  ev_timer_init(&rps_watcher, rps_cb, 0., 0.);
+  rps_watcher.data = this;
+
+#ifdef ENABLE_HTTP3
+  ev_timer_init(&quic.pkt_timer, quic_pkt_timeout_cb, 0., 0.);
+  quic.pkt_timer.data = this;
+#endif // ENABLE_HTTP3
 }
 
 Client::~Client() {
   disconnect();
 
+#ifdef ENABLE_HTTP3
+  if (config.is_quic()) {
+    quic_free();
+  }
+#endif // ENABLE_HTTP3
+
   if (ssl) {
     SSL_free(ssl);
   }
@@ -413,26 +518,59 @@ int Client::do_read() { return readfn(*this); }
 int Client::do_write() { return writefn(*this); }
 
 int Client::make_socket(addrinfo *addr) {
-  fd = util::create_nonblock_socket(addr->ai_family);
-  if (fd == -1) {
-    return -1;
-  }
-  if (config.scheme == "https") {
-    if (!ssl) {
-      ssl = SSL_new(worker->ssl_ctx);
+  int rv;
+
+  if (config.is_quic()) {
+#ifdef ENABLE_HTTP3
+    fd = util::create_nonblock_udp_socket(addr->ai_family);
+    if (fd == -1) {
+      return -1;
+    }
+
+    rv = util::bind_any_addr_udp(fd, addr->ai_family);
+    if (rv != 0) {
+      close(fd);
+      fd = -1;
+      return -1;
     }
 
-    auto config = worker->config;
+    socklen_t addrlen = sizeof(local_addr.su.storage);
+    rv = getsockname(fd, &local_addr.su.sa, &addrlen);
+    if (rv == -1) {
+      return -1;
+    }
+    local_addr.len = addrlen;
+
+    if (quic_init(&local_addr.su.sa, local_addr.len, addr->ai_addr,
+                  addr->ai_addrlen) != 0) {
+      std::cerr << "quic_init failed" << std::endl;
+      return -1;
+    }
+#endif // ENABLE_HTTP3
+  } else {
+    fd = util::create_nonblock_socket(addr->ai_family);
+    if (fd == -1) {
+      return -1;
+    }
+    if (config.scheme == "https") {
+      if (!ssl) {
+        ssl = SSL_new(worker->ssl_ctx);
+      }
 
-    if (!util::numeric_host(config->host.c_str())) {
-      SSL_set_tlsext_host_name(ssl, config->host.c_str());
+      SSL_set_fd(ssl, fd);
+      SSL_set_connect_state(ssl);
     }
+  }
+
+  if (ssl && !util::numeric_host(config.host.c_str())) {
+    SSL_set_tlsext_host_name(ssl, config.host.c_str());
+  }
 
-    SSL_set_fd(ssl, fd);
-    SSL_set_connect_state(ssl);
+  if (config.is_quic()) {
+    return 0;
   }
 
-  auto rv = ::connect(fd, addr->ai_addr, addr->ai_addrlen);
+  rv = ::connect(fd, addr->ai_addr, addr->ai_addrlen);
   if (rv != 0 && errno != EINPROGRESS) {
     if (ssl) {
       SSL_free(ssl);
@@ -489,13 +627,22 @@ int Client::connect() {
     current_addr = addr;
   }
 
-  writefn = &Client::connected;
-
   ev_io_set(&rev, fd, EV_READ);
   ev_io_set(&wev, fd, EV_WRITE);
 
   ev_io_start(worker->loop, &wev);
 
+  if (config.is_quic()) {
+#ifdef ENABLE_HTTP3
+    ev_io_start(worker->loop, &rev);
+
+    readfn = &Client::read_quic;
+    writefn = &Client::write_quic;
+#endif // ENABLE_HTTP3
+  } else {
+    writefn = &Client::connected;
+  }
+
   return 0;
 }
 
@@ -550,8 +697,18 @@ void Client::fail() {
 void Client::disconnect() {
   record_client_end_time();
 
+#ifdef ENABLE_HTTP3
+  if (config.is_quic()) {
+    quic_close_connection();
+  }
+#endif // ENABLE_HTTP3
+
+#ifdef ENABLE_HTTP3
+  ev_timer_stop(worker->loop, &quic.pkt_timer);
+#endif // ENABLE_HTTP3
   ev_timer_stop(worker->loop, &conn_inactivity_watcher);
   ev_timer_stop(worker->loop, &conn_active_watcher);
+  ev_timer_stop(worker->loop, &rps_watcher);
   ev_timer_stop(worker->loop, &request_timeout_watcher);
   streams.clear();
   session.reset();
@@ -672,6 +829,16 @@ void print_server_tmp_key(SSL *ssl) {
     std::cout << "DH " << EVP_PKEY_bits(key) << " bits" << std::endl;
     break;
   case EVP_PKEY_EC: {
+#  if OPENSSL_3_0_0_API
+    std::array<char, 64> curve_name;
+    const char *cname;
+    if (!EVP_PKEY_get_utf8_string_param(key, "group", curve_name.data(),
+                                        curve_name.size(), nullptr)) {
+      cname = "<unknown>";
+    } else {
+      cname = curve_name.data();
+    }
+#  else  // !OPENSSL_3_0_0_API
     auto ec = EVP_PKEY_get1_EC_KEY(key);
     auto ec_del = defer(EC_KEY_free, ec);
     auto nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
@@ -679,6 +846,7 @@ void print_server_tmp_key(SSL *ssl) {
     if (!cname) {
       cname = OBJ_nid2sn(nid);
     }
+#  endif // !OPENSSL_3_0_0_API
 
     std::cout << "ECDH " << cname << " " << EVP_PKEY_bits(key) << " bits"
               << std::endl;
@@ -711,7 +879,14 @@ void Client::report_app_info() {
 }
 
 void Client::terminate_session() {
-  session->terminate();
+#ifdef ENABLE_HTTP3
+  if (config.is_quic()) {
+    quic.close_requested = true;
+  }
+#endif // ENABLE_HTTP3
+  if (session) {
+    session->terminate();
+  }
   // http1 session needs writecb to tear down session.
   signal_write();
 }
@@ -866,8 +1041,18 @@ void Client::on_stream_close(int32_t stream_id, bool success, bool final) {
       if (!ev_is_active(&request_timeout_watcher)) {
         ev_feed_event(worker->loop, &request_timeout_watcher, EV_TIMER);
       }
-    } else if (submit_request() != 0) {
-      process_request_failure();
+    } else if (!config.rps_enabled()) {
+      if (submit_request() != 0) {
+        process_request_failure();
+      }
+    } else if (rps_req_pending) {
+      --rps_req_pending;
+      if (submit_request() != 0) {
+        process_request_failure();
+      }
+    } else {
+      assert(rps_req_inflight);
+      --rps_req_inflight;
     }
   }
 }
@@ -899,7 +1084,15 @@ int Client::connection_made() {
 
     if (next_proto) {
       auto proto = StringRef{next_proto, next_proto_len};
-      if (util::check_h2_is_selected(proto)) {
+      if (config.is_quic()) {
+#ifdef ENABLE_HTTP3
+        assert(session);
+        if (!util::streq(StringRef{&NGHTTP3_ALPN_H3[1]}, proto) &&
+            !util::streq_l("h3-29", proto)) {
+          return -1;
+        }
+#endif // ENABLE_HTTP3
+      } else if (util::check_h2_is_selected(proto)) {
         session = std::make_unique<Http2Session>(this);
       } else if (util::streq(NGHTTP2_H1_1, proto)) {
         session = std::make_unique<Http1Session>(this);
@@ -908,6 +1101,9 @@ int Client::connection_made() {
       // Just assign next_proto to selected_proto anyway to show the
       // negotiation result.
       selected_proto = proto.str();
+    } else if (config.is_quic()) {
+      std::cerr << "QUIC requires ALPN negotiation" << std::endl;
+      return -1;
     } else {
       std::cout << "No protocol negotiated. Fallback behaviour may be activated"
                 << std::endl;
@@ -962,10 +1158,25 @@ int Client::connection_made() {
 
   record_connect_time();
 
-  if (!config.timing_script) {
+  if (config.rps_enabled()) {
+    rps_watcher.repeat = std::max(0.01, 1. / config.rps);
+    ev_timer_again(worker->loop, &rps_watcher);
+    rps_duration_started = ev_now(worker->loop);
+  }
+
+  if (config.rps_enabled()) {
+    assert(req_left);
+
+    ++rps_req_inflight;
+
+    if (submit_request() != 0) {
+      process_request_failure();
+    }
+  } else if (!config.timing_script) {
     auto nreq = config.is_timing_based_mode()
                     ? std::max(req_left, session->max_concurrent_streams())
                     : std::min(req_left, session->max_concurrent_streams());
+
     for (; nreq > 0; --nreq) {
       if (submit_request() != 0) {
         process_request_failure();
@@ -1206,6 +1417,46 @@ int Client::write_tls() {
   return 0;
 }
 
+#ifdef ENABLE_HTTP3
+int Client::write_udp(const sockaddr *addr, socklen_t addrlen,
+                      const uint8_t *data, size_t datalen, size_t gso_size) {
+  iovec msg_iov;
+  msg_iov.iov_base = const_cast<uint8_t *>(data);
+  msg_iov.iov_len = datalen;
+
+  msghdr msg{};
+  msg.msg_name = const_cast<sockaddr *>(addr);
+  msg.msg_namelen = addrlen;
+  msg.msg_iov = &msg_iov;
+  msg.msg_iovlen = 1;
+
+#  ifdef UDP_SEGMENT
+  std::array<uint8_t, CMSG_SPACE(sizeof(uint16_t))> msg_ctrl{};
+  if (gso_size && datalen > gso_size) {
+    msg.msg_control = msg_ctrl.data();
+    msg.msg_controllen = msg_ctrl.size();
+
+    auto cm = CMSG_FIRSTHDR(&msg);
+    cm->cmsg_level = SOL_UDP;
+    cm->cmsg_type = UDP_SEGMENT;
+    cm->cmsg_len = CMSG_LEN(sizeof(uint16_t));
+    *(reinterpret_cast<uint16_t *>(CMSG_DATA(cm))) = gso_size;
+  }
+#  endif // UDP_SEGMENT
+
+  auto nwrite = sendmsg(fd, &msg, 0);
+  if (nwrite < 0) {
+    std::cerr << "sendto: errno=" << errno << std::endl;
+  } else {
+    ++worker->stats.udp_dgram_sent;
+  }
+
+  ev_io_stop(worker->loop, &wev);
+
+  return 0;
+}
+#endif // ENABLE_HTTP3
+
 void Client::record_request_time(RequestStat *req_stat) {
   req_stat->request_time = std::chrono::steady_clock::now();
   req_stat->request_wall_time = std::chrono::system_clock::now();
@@ -1324,7 +1575,7 @@ Worker::~Worker() {
 
 void Worker::stop_all_clients() {
   for (auto client : clients) {
-    if (client && client->session) {
+    if (client) {
       client->terminate_session();
     }
   }
@@ -1859,6 +2110,7 @@ Options:
               Default: 1
   -w, --window-bits=<N>
               Sets the stream level initial window size to (2**<N>)-1.
+              For QUIC, <N> is capped to 26 (roughly 64MiB).
               Default: )"
       << config.window_bits << R"(
   -W, --connection-window-bits=<N>
@@ -1869,10 +2121,15 @@ Options:
   -H, --header=<HEADER>
               Add/Override a header to the requests.
   --ciphers=<SUITE>
-              Set allowed  cipher list.  The  format of the  string is
-              described in OpenSSL ciphers(1).
+              Set  allowed cipher  list  for TLSv1.2  or ealier.   The
+              format of the string is described in OpenSSL ciphers(1).
               Default: )"
       << config.ciphers << R"(
+  --tls13-ciphers=<SUITE>
+              Set allowed cipher list for  TLSv1.3.  The format of the
+              string is described in OpenSSL ciphers(1).
+              Default: )"
+      << config.tls13_ciphers << R"(
   -p, --no-tls-proto=<PROTOID>
               Specify ALPN identifier of the  protocol to be used when
               accessing http URI without SSL/TLS.
@@ -1903,7 +2160,7 @@ Options:
               length of the period in time.  This option is ignored if
               the rate option is not used.  The default value for this
               option is 1s.
-  -D, --duration=<N>
+  -D, --duration=<DURATION>
               Specifies the main duration for the measurements in case
               of timing-based  benchmarking.  -D  and -r  are mutually
               exclusive.
@@ -1943,7 +2200,8 @@ Options:
               port defined in  the first URI are  used solely.  Values
               contained  in  other  URIs,  if  present,  are  ignored.
               Definition of a  base URI overrides all  scheme, host or
-              port values.
+              port   values.   --timing-script-file   and  --rps   are
+              mutually exclusive.
   -B, --base-uri=(<URI>|unix:<PATH>)
               Specify URI from which the scheme, host and port will be
               used  for  all requests.   The  base  URI overrides  all
@@ -1985,9 +2243,26 @@ Options:
               response  time when  using  one worker  thread, but  may
               appear slightly  out of order with  multiple threads due
               to buffering.  Status code is -1 for failed streams.
+  --qlog-file-base=<PATH>
+              Enable qlog output and specify base file name for qlogs.
+              Qlog  is emitted  for each connection.
+              For  a  given  base  name "base", each  output file name
+              becomes  "base.M.N.qlog"  where M is worker ID  and N is
+              client ID (e.g. "base.0.3.qlog").
+              Only effective in QUIC runs.
   --connect-to=<HOST>[:<PORT>]
               Host and port to connect  instead of using the authority
               in <URI>.
+  --rps=<N>   Specify request  per second for each  client.  --rps and
+              --timing-script-file are mutually exclusive.
+  --groups=<GROUPS>
+              Specify the supported groups.
+              Default: )"
+      << config.groups << R"(
+  --no-udp-gso
+              Disable UDP GSO.
+  --max-udp-payload-size=<SIZE>
+              Specify the maximum outgoing UDP datagram payload size.
   -v, --verbose
               Output debug information.
   --version   Display version information and exit.
@@ -2015,6 +2290,7 @@ int main(int argc, char **argv) {
 
   std::string datafile;
   std::string logfile;
+  std::string qlog_base;
   bool nreqs_set_manually = false;
   while (1) {
     static int flag = 0;
@@ -2047,6 +2323,12 @@ int main(int argc, char **argv) {
         {"warm-up-time", required_argument, &flag, 9},
         {"log-file", required_argument, &flag, 10},
         {"connect-to", required_argument, &flag, 11},
+        {"rps", required_argument, &flag, 12},
+        {"groups", required_argument, &flag, 13},
+        {"tls13-ciphers", required_argument, &flag, 14},
+        {"no-udp-gso", no_argument, &flag, 15},
+        {"qlog-file-base", required_argument, &flag, 16},
+        {"max-udp-payload-size", required_argument, &flag, 17},
         {nullptr, 0, nullptr, 0}};
     int option_index = 0;
     auto c = getopt_long(argc, argv,
@@ -2199,10 +2481,9 @@ int main(int argc, char **argv) {
       break;
     }
     case 'D':
-      config.duration = strtoul(optarg, nullptr, 10);
-      if (config.duration == 0) {
-        std::cerr << "-D: the main duration for timing-based benchmarking "
-                  << "must be positive." << std::endl;
+      config.duration = util::parse_duration_with_unit(optarg);
+      if (!std::isfinite(config.duration)) {
+        std::cerr << "-D: value error " << optarg << std::endl;
         exit(EXIT_FAILURE);
       }
       break;
@@ -2287,6 +2568,49 @@ int main(int argc, char **argv) {
         config.connect_to_port = port;
         break;
       }
+      case 12: {
+        char *end;
+        auto v = std::strtod(optarg, &end);
+        if (end == optarg || *end != '\0' || !std::isfinite(v) ||
+            1. / v < 1e-6) {
+          std::cerr << "--rps: Invalid value " << optarg << std::endl;
+          exit(EXIT_FAILURE);
+        }
+        config.rps = v;
+        break;
+      }
+      case 13:
+        // --groups
+        config.groups = optarg;
+        break;
+      case 14:
+        // --tls13-ciphers
+        config.tls13_ciphers = optarg;
+        break;
+      case 15:
+        // --no-udp-gso
+        config.no_udp_gso = true;
+        break;
+      case 16:
+        // --qlog-file-base
+        qlog_base = optarg;
+        break;
+      case 17: {
+        // --max-udp-payload-size
+        auto n = util::parse_uint_with_unit(optarg);
+        if (n == -1) {
+          std::cerr << "--max-udp-payload-size: bad option value: " << optarg
+                    << std::endl;
+          exit(EXIT_FAILURE);
+        }
+        if (static_cast<uint64_t>(n) > 64_k) {
+          std::cerr << "--max-udp-payload-size: must not exceed 65536"
+                    << std::endl;
+          exit(EXIT_FAILURE);
+        }
+        config.max_udp_payload_size = n;
+        break;
+      }
       }
       break;
     default:
@@ -2377,6 +2701,12 @@ int main(int argc, char **argv) {
     exit(EXIT_FAILURE);
   }
 
+  if (config.timing_script && config.rps_enabled()) {
+    std::cerr << "--timing-script-file, --rps: they are mutually exclusive."
+              << std::endl;
+    exit(EXIT_FAILURE);
+  }
+
   if (config.nreqs == 0 && !config.is_timing_based_mode()) {
     std::cerr << "-n: the number of requests must be strictly greater than 0 "
                  "if timing-based test is not being run."
@@ -2447,6 +2777,13 @@ int main(int argc, char **argv) {
       exit(EXIT_FAILURE);
     }
     config.data_length = data_stat.st_size;
+    auto addr = mmap(nullptr, config.data_length, PROT_READ, MAP_SHARED,
+                     config.data_fd, 0);
+    if (addr == MAP_FAILED) {
+      std::cerr << "-d: Could not mmap file " << datafile << std::endl;
+      exit(EXIT_FAILURE);
+    }
+    config.data = static_cast<uint8_t *>(addr);
   }
 
   if (!logfile.empty()) {
@@ -2458,11 +2795,23 @@ int main(int argc, char **argv) {
     }
   }
 
+  if (!qlog_base.empty()) {
+    if (!config.is_quic()) {
+      std::cerr
+          << "Warning: --qlog-file-base: only effective in quic, ignoring."
+          << std::endl;
+    } else {
+#ifdef ENABLE_HTTP3
+      config.qlog_file_base = qlog_base;
+#endif // ENABLE_HTTP3
+    }
+  }
+
   struct sigaction act {};
   act.sa_handler = SIG_IGN;
   sigaction(SIGPIPE, &act, nullptr);
 
-  auto ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+  auto ssl_ctx = SSL_CTX_new(TLS_client_method());
   if (!ssl_ctx) {
     std::cerr << "Failed to create SSL_CTX: "
               << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
@@ -2477,9 +2826,14 @@ int main(int argc, char **argv) {
   SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
   SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
 
-  if (nghttp2::tls::ssl_ctx_set_proto_versions(
-          ssl_ctx, nghttp2::tls::NGHTTP2_TLS_MIN_VERSION,
-          nghttp2::tls::NGHTTP2_TLS_MAX_VERSION) != 0) {
+  if (config.is_quic()) {
+#ifdef ENABLE_HTTP3
+    SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
+    SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
+#endif // ENABLE_HTTP3
+  } else if (nghttp2::tls::ssl_ctx_set_proto_versions(
+                 ssl_ctx, nghttp2::tls::NGHTTP2_TLS_MIN_VERSION,
+                 nghttp2::tls::NGHTTP2_TLS_MAX_VERSION) != 0) {
     std::cerr << "Could not set TLS versions" << std::endl;
     exit(EXIT_FAILURE);
   }
@@ -2491,6 +2845,27 @@ int main(int argc, char **argv) {
     exit(EXIT_FAILURE);
   }
 
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+  if (SSL_CTX_set_ciphersuites(ssl_ctx, config.tls13_ciphers.c_str()) == 0) {
+    std::cerr << "SSL_CTX_set_ciphersuites with " << config.tls13_ciphers
+              << " failed: " << ERR_error_string(ERR_get_error(), nullptr)
+              << std::endl;
+    exit(EXIT_FAILURE);
+  }
+#endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+  if (SSL_CTX_set1_groups_list(ssl_ctx, config.groups.c_str()) != 1) {
+    std::cerr << "SSL_CTX_set1_groups_list failed" << std::endl;
+    exit(EXIT_FAILURE);
+  }
+#else  // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
+  if (SSL_CTX_set1_curves_list(ssl_ctx, config.groups.c_str()) != 1) {
+    std::cerr << "SSL_CTX_set1_curves_list failed" << std::endl;
+    exit(EXIT_FAILURE);
+  }
+#endif // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
+
 #ifndef OPENSSL_NO_NEXTPROTONEG
   SSL_CTX_set_next_proto_select_cb(ssl_ctx, client_select_next_proto_cb,
                                    nullptr);
@@ -2505,6 +2880,16 @@ int main(int argc, char **argv) {
   SSL_CTX_set_alpn_protos(ssl_ctx, proto_list.data(), proto_list.size());
 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
 
+#if OPENSSL_1_1_1_API
+  auto keylog_filename = getenv("SSLKEYLOGFILE");
+  if (keylog_filename) {
+    keylog_file.open(keylog_filename, std::ios_base::app);
+    if (keylog_file) {
+      SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
+    }
+  }
+#endif // OPENSSL_1_1_1_API
+
   std::string user_agent = "h2load nghttp2/" NGHTTP2_VERSION;
   Headers shared_nva;
   shared_nva.emplace_back(":scheme", config.scheme);
@@ -2723,6 +3108,8 @@ int main(int argc, char **argv) {
     stats.bytes_head += s.bytes_head;
     stats.bytes_head_decomp += s.bytes_head_decomp;
     stats.bytes_body += s.bytes_body;
+    stats.udp_dgram_recv += s.udp_dgram_recv;
+    stats.udp_dgram_sent += s.udp_dgram_sent;
 
     for (size_t i = 0; i < stats.status.size(); ++i) {
       stats.status[i] += s.status[i];
@@ -2781,30 +3168,37 @@ traffic: )" << util::utos_funit(stats.bytes_total)
             << util::utos_funit(stats.bytes_head) << "B (" << stats.bytes_head
             << ") headers (space savings " << header_space_savings * 100
             << "%), " << util::utos_funit(stats.bytes_body) << "B ("
-            << stats.bytes_body << R"() data
-                     min         max         mean         sd        +/- sd
+            << stats.bytes_body << R"() data)" << std::endl;
+#ifdef ENABLE_HTTP3
+  if (config.is_quic()) {
+    std::cout << "UDP datagram: " << stats.udp_dgram_sent << " sent, "
+              << stats.udp_dgram_recv << " received" << std::endl;
+  }
+#endif // ENABLE_HTTP3
+  std::cout
+      << R"(                     min         max         mean         sd        +/- sd
 time for request: )"
-            << std::setw(10) << util::format_duration(ts.request.min) << "  "
-            << std::setw(10) << util::format_duration(ts.request.max) << "  "
-            << std::setw(10) << util::format_duration(ts.request.mean) << "  "
-            << std::setw(10) << util::format_duration(ts.request.sd)
-            << std::setw(9) << util::dtos(ts.request.within_sd) << "%"
-            << "\ntime for connect: " << std::setw(10)
-            << util::format_duration(ts.connect.min) << "  " << std::setw(10)
-            << util::format_duration(ts.connect.max) << "  " << std::setw(10)
-            << util::format_duration(ts.connect.mean) << "  " << std::setw(10)
-            << util::format_duration(ts.connect.sd) << std::setw(9)
-            << util::dtos(ts.connect.within_sd) << "%"
-            << "\ntime to 1st byte: " << std::setw(10)
-            << util::format_duration(ts.ttfb.min) << "  " << std::setw(10)
-            << util::format_duration(ts.ttfb.max) << "  " << std::setw(10)
-            << util::format_duration(ts.ttfb.mean) << "  " << std::setw(10)
-            << util::format_duration(ts.ttfb.sd) << std::setw(9)
-            << util::dtos(ts.ttfb.within_sd) << "%"
-            << "\nreq/s           : " << std::setw(10) << ts.rps.min << "  "
-            << std::setw(10) << ts.rps.max << "  " << std::setw(10)
-            << ts.rps.mean << "  " << std::setw(10) << ts.rps.sd << std::setw(9)
-            << util::dtos(ts.rps.within_sd) << "%" << std::endl;
+      << std::setw(10) << util::format_duration(ts.request.min) << "  "
+      << std::setw(10) << util::format_duration(ts.request.max) << "  "
+      << std::setw(10) << util::format_duration(ts.request.mean) << "  "
+      << std::setw(10) << util::format_duration(ts.request.sd) << std::setw(9)
+      << util::dtos(ts.request.within_sd) << "%"
+      << "\ntime for connect: " << std::setw(10)
+      << util::format_duration(ts.connect.min) << "  " << std::setw(10)
+      << util::format_duration(ts.connect.max) << "  " << std::setw(10)
+      << util::format_duration(ts.connect.mean) << "  " << std::setw(10)
+      << util::format_duration(ts.connect.sd) << std::setw(9)
+      << util::dtos(ts.connect.within_sd) << "%"
+      << "\ntime to 1st byte: " << std::setw(10)
+      << util::format_duration(ts.ttfb.min) << "  " << std::setw(10)
+      << util::format_duration(ts.ttfb.max) << "  " << std::setw(10)
+      << util::format_duration(ts.ttfb.mean) << "  " << std::setw(10)
+      << util::format_duration(ts.ttfb.sd) << std::setw(9)
+      << util::dtos(ts.ttfb.within_sd) << "%"
+      << "\nreq/s           : " << std::setw(10) << ts.rps.min << "  "
+      << std::setw(10) << ts.rps.max << "  " << std::setw(10) << ts.rps.mean
+      << "  " << std::setw(10) << ts.rps.sd << std::setw(9)
+      << util::dtos(ts.rps.within_sd) << "%" << std::endl;
 
   SSL_CTX_free(ssl_ctx);
 
index ca68997..67da2b5 100644 (file)
 
 #include <nghttp2/nghttp2.h>
 
+#ifdef ENABLE_HTTP3
+#  include <ngtcp2/ngtcp2.h>
+#  include <ngtcp2/ngtcp2_crypto.h>
+#endif // ENABLE_HTTP3
+
 #include <ev.h>
 
 #include <openssl/ssl.h>
 
 #include "http2.h"
+#ifdef ENABLE_HTTP3
+#  include "quic.h"
+#endif // ENABLE_HTTP3
 #include "memchunk.h"
 #include "template.h"
 
@@ -72,8 +80,13 @@ struct Config {
   std::string connect_to_host;
   std::string ifile;
   std::string ciphers;
+  std::string tls13_ciphers;
+  // supported groups (or curves).
+  std::string groups;
   // length of upload data
   int64_t data_length;
+  // memory mapped upload data
+  uint8_t *data;
   addrinfo *addrs;
   size_t nreqs;
   size_t nclients;
@@ -100,6 +113,8 @@ struct Config {
   int data_fd;
   // file descriptor to write per-request stats to.
   int log_fd;
+  // base file name of qlog output files
+  std::string qlog_file_base;
   uint16_t port;
   uint16_t default_port;
   uint16_t connect_to_port;
@@ -114,6 +129,12 @@ struct Config {
   // list of supported NPN/ALPN protocol strings in the order of
   // preference.
   std::vector<std::string> npn_list;
+  // The number of request per second for each client.
+  double rps;
+  // Disables GSO for UDP connections.
+  bool no_udp_gso;
+  // The maximum UDP datagram payload size to send.
+  size_t max_udp_payload_size;
 
   Config();
   ~Config();
@@ -121,6 +142,8 @@ struct Config {
   bool is_rate_mode() const;
   bool is_timing_based_mode() const;
   bool has_base_uri() const;
+  bool rps_enabled() const;
+  bool is_quic() const;
 };
 
 struct RequestStat {
@@ -215,8 +238,12 @@ struct Stats {
   std::array<size_t, 6> status;
   // The statistics per request
   std::vector<RequestStat> req_stats;
-  // THe statistics per client
+  // The statistics per client
   std::vector<ClientStat> client_stats;
+  // The number of UDP datagrams received.
+  size_t udp_dgram_recv;
+  // The number of UDP datagrams sent.
+  size_t udp_dgram_sent;
 };
 
 enum ClientState { CLIENT_IDLE, CLIENT_CONNECTED };
@@ -306,6 +333,15 @@ struct Client {
   std::function<int(Client &)> readfn, writefn;
   Worker *worker;
   SSL *ssl;
+#ifdef ENABLE_HTTP3
+  struct {
+    ev_timer pkt_timer;
+    ngtcp2_conn *conn;
+    quic::Error last_error;
+    bool close_requested;
+    FILE *qlog_file;
+  } quic;
+#endif // ENABLE_HTTP3
   ev_timer request_timeout_watcher;
   addrinfo *next_addr;
   // Address for the current address.  When try_new_connection() is
@@ -329,6 +365,7 @@ struct Client {
   // The client id per worker
   uint32_t id;
   int fd;
+  Address local_addr;
   ev_timer conn_active_watcher;
   ev_timer conn_inactivity_watcher;
   std::string selected_proto;
@@ -336,6 +373,20 @@ struct Client {
   // true if the current connection will be closed, and no more new
   // request cannot be processed.
   bool final;
+  // rps_watcher is a timer to invoke callback periodically to
+  // generate a new request.
+  ev_timer rps_watcher;
+  // The timestamp that starts the period which contributes to the
+  // next request generation.
+  ev_tstamp rps_duration_started;
+  // The number of requests allowed by rps, but limited by stream
+  // concurrency.
+  size_t rps_req_pending;
+  // The number of in-flight streams.  req_inflight has similar value
+  // but it only measures requests made during Phase::MAIN_DURATION.
+  // rps_req_inflight measures the number of requests in all phases,
+  // and it is only used if --rps is given.
+  size_t rps_req_inflight;
 
   enum { ERR_CONNECT_FAIL = -100 };
 
@@ -402,6 +453,39 @@ struct Client {
   void record_client_end_time();
 
   void signal_write();
+
+#ifdef ENABLE_HTTP3
+  // QUIC
+  int quic_init(const sockaddr *local_addr, socklen_t local_addrlen,
+                const sockaddr *remote_addr, socklen_t remote_addrlen);
+  void quic_free();
+  int read_quic();
+  int write_quic();
+  int write_udp(const sockaddr *addr, socklen_t addrlen, const uint8_t *data,
+                size_t datalen, size_t gso_size);
+  void quic_close_connection();
+
+  int quic_handshake_completed();
+  int quic_recv_stream_data(uint32_t flags, int64_t stream_id,
+                            const uint8_t *data, size_t datalen);
+  int quic_acked_stream_data_offset(int64_t stream_id, size_t datalen);
+  int quic_stream_close(int64_t stream_id, uint64_t app_error_code);
+  int quic_stream_reset(int64_t stream_id, uint64_t app_error_code);
+  int quic_stream_stop_sending(int64_t stream_id, uint64_t app_error_code);
+  int quic_extend_max_local_streams();
+
+  int quic_on_rx_secret(ngtcp2_crypto_level level, const uint8_t *secret,
+                        size_t secretlen);
+  int quic_on_tx_secret(ngtcp2_crypto_level level, const uint8_t *secret,
+                        size_t secretlen);
+  void quic_set_tls_alert(uint8_t alert);
+
+  void quic_write_client_handshake(ngtcp2_crypto_level level,
+                                   const uint8_t *data, size_t datalen);
+  int quic_pkt_timeout();
+  void quic_restart_pkt_timer();
+  void quic_write_qlog(const void *data, size_t datalen);
+#endif // ENABLE_HTTP3
 };
 
 } // namespace h2load
index 28ad456..06c474c 100644 (file)
@@ -106,23 +106,6 @@ int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
 } // namespace
 
 namespace {
-int on_frame_not_send_callback(nghttp2_session *session,
-                               const nghttp2_frame *frame, int lib_error_code,
-                               void *user_data) {
-  if (frame->hd.type != NGHTTP2_HEADERS ||
-      frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
-    return 0;
-  }
-
-  auto client = static_cast<Client *>(user_data);
-  // request was not sent.  Mark it as error.
-  client->on_stream_close(frame->hd.stream_id, false);
-
-  return 0;
-}
-} // namespace
-
-namespace {
 int before_frame_send_callback(nghttp2_session *session,
                                const nghttp2_frame *frame, void *user_data) {
   if (frame->hd.type != NGHTTP2_HEADERS ||
@@ -211,9 +194,6 @@ void Http2Session::on_connect() {
   nghttp2_session_callbacks_set_on_header_callback(callbacks,
                                                    on_header_callback);
 
-  nghttp2_session_callbacks_set_on_frame_not_send_callback(
-      callbacks, on_frame_not_send_callback);
-
   nghttp2_session_callbacks_set_before_frame_send_callback(
       callbacks, before_frame_send_callback);
 
diff --git a/src/h2load_http3_session.cc b/src/h2load_http3_session.cc
new file mode 100644 (file)
index 0000000..40970f7
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2019 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "h2load_http3_session.h"
+
+#include <iostream>
+
+#include <ngtcp2/ngtcp2.h>
+
+#include "h2load.h"
+
+namespace h2load {
+
+Http3Session::Http3Session(Client *client)
+    : client_(client), conn_(nullptr), npending_request_(0), reqidx_(0) {}
+
+Http3Session::~Http3Session() { nghttp3_conn_del(conn_); }
+
+void Http3Session::on_connect() {}
+
+int Http3Session::submit_request() {
+  if (npending_request_) {
+    ++npending_request_;
+    return 0;
+  }
+
+  auto config = client_->worker->config;
+  reqidx_ = client_->reqidx;
+
+  if (++client_->reqidx == config->nva.size()) {
+    client_->reqidx = 0;
+  }
+
+  auto stream_id = submit_request_internal();
+  if (stream_id < 0) {
+    if (stream_id == NGTCP2_ERR_STREAM_ID_BLOCKED) {
+      ++npending_request_;
+      return 0;
+    }
+    return -1;
+  }
+
+  return 0;
+}
+
+namespace {
+nghttp3_ssize read_data(nghttp3_conn *conn, int64_t stream_id, nghttp3_vec *vec,
+                        size_t veccnt, uint32_t *pflags, void *user_data,
+                        void *stream_user_data) {
+  auto s = static_cast<Http3Session *>(user_data);
+
+  s->read_data(vec, veccnt, pflags);
+
+  return 1;
+}
+} // namespace
+
+void Http3Session::read_data(nghttp3_vec *vec, size_t veccnt,
+                             uint32_t *pflags) {
+  assert(veccnt > 0);
+
+  auto config = client_->worker->config;
+
+  vec[0].base = config->data;
+  vec[0].len = config->data_length;
+  *pflags |= NGHTTP3_DATA_FLAG_EOF;
+}
+
+int64_t Http3Session::submit_request_internal() {
+  int rv;
+  int64_t stream_id;
+
+  auto config = client_->worker->config;
+  auto &nva = config->nva[reqidx_];
+
+  rv = ngtcp2_conn_open_bidi_stream(client_->quic.conn, &stream_id, nullptr);
+  if (rv != 0) {
+    return rv;
+  }
+
+  nghttp3_data_reader dr{};
+  dr.read_data = h2load::read_data;
+
+  rv = nghttp3_conn_submit_request(
+      conn_, stream_id, reinterpret_cast<nghttp3_nv *>(nva.data()), nva.size(),
+      config->data_fd == -1 ? nullptr : &dr, nullptr);
+  if (rv != 0) {
+    return rv;
+  }
+
+  client_->on_request(stream_id);
+  auto req_stat = client_->get_req_stat(stream_id);
+  assert(req_stat);
+  client_->record_request_time(req_stat);
+
+  return stream_id;
+}
+
+int Http3Session::on_read(const uint8_t *data, size_t len) { return -1; }
+
+int Http3Session::on_write() { return -1; }
+
+void Http3Session::terminate() {}
+
+size_t Http3Session::max_concurrent_streams() {
+  return (size_t)client_->worker->config->max_concurrent_streams;
+}
+
+namespace {
+int stream_close(nghttp3_conn *conn, int64_t stream_id, uint64_t app_error_code,
+                 void *user_data, void *stream_user_data) {
+  auto s = static_cast<Http3Session *>(user_data);
+  if (s->stream_close(stream_id, app_error_code) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+  return 0;
+}
+} // namespace
+
+int Http3Session::stream_close(int64_t stream_id, uint64_t app_error_code) {
+  if (!ngtcp2_is_bidi_stream(stream_id)) {
+    assert(!ngtcp2_conn_is_local_stream(client_->quic.conn, stream_id));
+    ngtcp2_conn_extend_max_streams_uni(client_->quic.conn, 1);
+  }
+  client_->on_stream_close(stream_id, app_error_code == NGHTTP3_H3_NO_ERROR);
+  return 0;
+}
+
+namespace {
+int recv_data(nghttp3_conn *conn, int64_t stream_id, const uint8_t *data,
+              size_t datalen, void *user_data, void *stream_user_data) {
+  auto s = static_cast<Http3Session *>(user_data);
+  s->recv_data(stream_id, data, datalen);
+  return 0;
+}
+} // namespace
+
+void Http3Session::recv_data(int64_t stream_id, const uint8_t *data,
+                             size_t datalen) {
+  client_->record_ttfb();
+  client_->worker->stats.bytes_body += datalen;
+  consume(stream_id, datalen);
+}
+
+namespace {
+int deferred_consume(nghttp3_conn *conn, int64_t stream_id, size_t nconsumed,
+                     void *user_data, void *stream_user_data) {
+  auto s = static_cast<Http3Session *>(user_data);
+  s->consume(stream_id, nconsumed);
+  return 0;
+}
+} // namespace
+
+void Http3Session::consume(int64_t stream_id, size_t nconsumed) {
+  ngtcp2_conn_extend_max_stream_offset(client_->quic.conn, stream_id,
+                                       nconsumed);
+  ngtcp2_conn_extend_max_offset(client_->quic.conn, nconsumed);
+}
+
+namespace {
+int begin_headers(nghttp3_conn *conn, int64_t stream_id, void *user_data,
+                  void *stream_user_data) {
+  auto s = static_cast<Http3Session *>(user_data);
+  s->begin_headers(stream_id);
+  return 0;
+}
+} // namespace
+
+void Http3Session::begin_headers(int64_t stream_id) {
+  auto payloadlen = nghttp3_conn_get_frame_payload_left(conn_, stream_id);
+  assert(payloadlen > 0);
+
+  client_->worker->stats.bytes_head += payloadlen;
+}
+
+namespace {
+int recv_header(nghttp3_conn *conn, int64_t stream_id, int32_t token,
+                nghttp3_rcbuf *name, nghttp3_rcbuf *value, uint8_t flags,
+                void *user_data, void *stream_user_data) {
+  auto s = static_cast<Http3Session *>(user_data);
+  auto k = nghttp3_rcbuf_get_buf(name);
+  auto v = nghttp3_rcbuf_get_buf(value);
+  s->recv_header(stream_id, &k, &v);
+  return 0;
+}
+} // namespace
+
+void Http3Session::recv_header(int64_t stream_id, const nghttp3_vec *name,
+                               const nghttp3_vec *value) {
+  client_->on_header(stream_id, name->base, name->len, value->base, value->len);
+  client_->worker->stats.bytes_head_decomp += name->len + value->len;
+}
+
+namespace {
+int send_stop_sending(nghttp3_conn *conn, int64_t stream_id,
+                      uint64_t app_error_code, void *user_data,
+                      void *stream_user_data) {
+  auto s = static_cast<Http3Session *>(user_data);
+  if (s->send_stop_sending(stream_id, app_error_code) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+  return 0;
+}
+} // namespace
+
+int Http3Session::send_stop_sending(int64_t stream_id,
+                                    uint64_t app_error_code) {
+  auto rv = ngtcp2_conn_shutdown_stream_read(client_->quic.conn, stream_id,
+                                             app_error_code);
+  if (rv != 0) {
+    std::cerr << "ngtcp2_conn_shutdown_stream_read: " << ngtcp2_strerror(rv)
+              << std::endl;
+    return -1;
+  }
+  return 0;
+}
+
+int Http3Session::close_stream(int64_t stream_id, uint64_t app_error_code) {
+  auto rv = nghttp3_conn_close_stream(conn_, stream_id, app_error_code);
+  switch (rv) {
+  case 0:
+    return 0;
+  case NGHTTP3_ERR_STREAM_NOT_FOUND:
+    if (!ngtcp2_is_bidi_stream(stream_id)) {
+      assert(!ngtcp2_conn_is_local_stream(client_->quic.conn, stream_id));
+      ngtcp2_conn_extend_max_streams_uni(client_->quic.conn, 1);
+    }
+    return 0;
+  default:
+    return -1;
+  }
+}
+
+int Http3Session::shutdown_stream_read(int64_t stream_id) {
+  auto rv = nghttp3_conn_shutdown_stream_read(conn_, stream_id);
+  if (rv != 0) {
+    return -1;
+  }
+  return 0;
+}
+
+int Http3Session::extend_max_local_streams() {
+  auto config = client_->worker->config;
+
+  for (; npending_request_; --npending_request_) {
+    auto stream_id = submit_request_internal();
+    if (stream_id < 0) {
+      if (stream_id == NGTCP2_ERR_STREAM_ID_BLOCKED) {
+        return 0;
+      }
+      return -1;
+    }
+
+    if (++reqidx_ == config->nva.size()) {
+      reqidx_ = 0;
+    }
+  }
+
+  return 0;
+}
+
+int Http3Session::init_conn() {
+  int rv;
+
+  assert(conn_ == nullptr);
+
+  if (ngtcp2_conn_get_max_local_streams_uni(client_->quic.conn) < 3) {
+    return -1;
+  }
+
+  nghttp3_callbacks callbacks{
+      nullptr, // acked_stream_data
+      h2load::stream_close,
+      h2load::recv_data,
+      h2load::deferred_consume,
+      h2load::begin_headers,
+      h2load::recv_header,
+      nullptr, // end_headers
+      nullptr, // begin_trailers
+      h2load::recv_header,
+      nullptr, // end_trailers
+      h2load::send_stop_sending,
+  };
+
+  auto config = client_->worker->config;
+
+  nghttp3_settings settings;
+  nghttp3_settings_default(&settings);
+  settings.qpack_max_table_capacity = config->header_table_size;
+  settings.qpack_blocked_streams = 100;
+
+  auto mem = nghttp3_mem_default();
+
+  rv = nghttp3_conn_client_new(&conn_, &callbacks, &settings, mem, this);
+  if (rv != 0) {
+    std::cerr << "nghttp3_conn_client_new: " << nghttp3_strerror(rv)
+              << std::endl;
+    return -1;
+  }
+
+  int64_t ctrl_stream_id;
+
+  rv = ngtcp2_conn_open_uni_stream(client_->quic.conn, &ctrl_stream_id, NULL);
+  if (rv != 0) {
+    std::cerr << "ngtcp2_conn_open_uni_stream: " << ngtcp2_strerror(rv)
+              << std::endl;
+    return -1;
+  }
+
+  rv = nghttp3_conn_bind_control_stream(conn_, ctrl_stream_id);
+  if (rv != 0) {
+    std::cerr << "nghttp3_conn_bind_control_stream: " << nghttp3_strerror(rv)
+              << std::endl;
+    return -1;
+  }
+
+  int64_t qpack_enc_stream_id, qpack_dec_stream_id;
+
+  rv = ngtcp2_conn_open_uni_stream(client_->quic.conn, &qpack_enc_stream_id,
+                                   NULL);
+  if (rv != 0) {
+    std::cerr << "ngtcp2_conn_open_uni_stream: " << ngtcp2_strerror(rv)
+              << std::endl;
+    return -1;
+  }
+
+  rv = ngtcp2_conn_open_uni_stream(client_->quic.conn, &qpack_dec_stream_id,
+                                   NULL);
+  if (rv != 0) {
+    std::cerr << "ngtcp2_conn_open_uni_stream: " << ngtcp2_strerror(rv)
+              << std::endl;
+    return -1;
+  }
+
+  rv = nghttp3_conn_bind_qpack_streams(conn_, qpack_enc_stream_id,
+                                       qpack_dec_stream_id);
+  if (rv != 0) {
+    std::cerr << "nghttp3_conn_bind_qpack_streams: " << nghttp3_strerror(rv)
+              << std::endl;
+    return -1;
+  }
+
+  return 0;
+}
+
+ssize_t Http3Session::read_stream(uint32_t flags, int64_t stream_id,
+                                  const uint8_t *data, size_t datalen) {
+  auto nconsumed = nghttp3_conn_read_stream(
+      conn_, stream_id, data, datalen, flags & NGTCP2_STREAM_DATA_FLAG_FIN);
+  if (nconsumed < 0) {
+    std::cerr << "nghttp3_conn_read_stream: " << nghttp3_strerror(nconsumed)
+              << std::endl;
+    client_->quic.last_error = quic::err_application(nconsumed);
+    return -1;
+  }
+  return nconsumed;
+}
+
+ssize_t Http3Session::write_stream(int64_t &stream_id, int &fin,
+                                   nghttp3_vec *vec, size_t veccnt) {
+  auto sveccnt =
+      nghttp3_conn_writev_stream(conn_, &stream_id, &fin, vec, veccnt);
+  if (sveccnt < 0) {
+    client_->quic.last_error = quic::err_application(sveccnt);
+    return -1;
+  }
+  return sveccnt;
+}
+
+int Http3Session::block_stream(int64_t stream_id) {
+  auto rv = nghttp3_conn_block_stream(conn_, stream_id);
+  if (rv != 0) {
+    client_->quic.last_error = quic::err_application(rv);
+    return -1;
+  }
+  return 0;
+}
+
+int Http3Session::shutdown_stream_write(int64_t stream_id) {
+  auto rv = nghttp3_conn_shutdown_stream_write(conn_, stream_id);
+  if (rv != 0) {
+    client_->quic.last_error = quic::err_application(rv);
+    return -1;
+  }
+  return 0;
+}
+
+int Http3Session::add_write_offset(int64_t stream_id, size_t ndatalen) {
+  auto rv = nghttp3_conn_add_write_offset(conn_, stream_id, ndatalen);
+  if (rv != 0) {
+    client_->quic.last_error = quic::err_application(rv);
+    return -1;
+  }
+  return 0;
+}
+
+int Http3Session::add_ack_offset(int64_t stream_id, size_t datalen) {
+  auto rv = nghttp3_conn_add_ack_offset(conn_, stream_id, datalen);
+  if (rv != 0) {
+    client_->quic.last_error = quic::err_application(rv);
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace h2load
diff --git a/src/h2load_http3_session.h b/src/h2load_http3_session.h
new file mode 100644 (file)
index 0000000..27ff025
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2019 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef H2LOAD_HTTP3_SESSION_H
+#define H2LOAD_HTTP3_SESSION_H
+
+#include "h2load_session.h"
+
+#include <nghttp3/nghttp3.h>
+
+namespace h2load {
+
+struct Client;
+
+class Http3Session : public Session {
+public:
+  Http3Session(Client *client);
+  virtual ~Http3Session();
+  virtual void on_connect();
+  virtual int submit_request();
+  virtual int on_read(const uint8_t *data, size_t len);
+  virtual int on_write();
+  virtual void terminate();
+  virtual size_t max_concurrent_streams();
+
+  int init_conn();
+  int stream_close(int64_t stream_id, uint64_t app_error_code);
+  void recv_data(int64_t stream_id, const uint8_t *data, size_t datalen);
+  void consume(int64_t stream_id, size_t nconsumed);
+  void begin_headers(int64_t stream_id);
+  void recv_header(int64_t stream_id, const nghttp3_vec *name,
+                   const nghttp3_vec *value);
+  int send_stop_sending(int64_t stream_id, uint64_t app_error_code);
+
+  int close_stream(int64_t stream_id, uint64_t app_error_code);
+  int shutdown_stream_read(int64_t stream_id);
+  int extend_max_local_streams();
+  int64_t submit_request_internal();
+
+  ssize_t read_stream(uint32_t flags, int64_t stream_id, const uint8_t *data,
+                      size_t datalen);
+  ssize_t write_stream(int64_t &stream_id, int &fin, nghttp3_vec *vec,
+                       size_t veccnt);
+  int block_stream(int64_t stream_id);
+  int shutdown_stream_write(int64_t stream_id);
+  int add_write_offset(int64_t stream_id, size_t ndatalen);
+  int add_ack_offset(int64_t stream_id, size_t datalen);
+
+  void read_data(nghttp3_vec *vec, size_t veccnt, uint32_t *pflags);
+
+private:
+  Client *client_;
+  nghttp3_conn *conn_;
+  size_t npending_request_;
+  size_t reqidx_;
+};
+
+} // namespace h2load
+
+#endif // H2LOAD_HTTP3_SESSION_H
diff --git a/src/h2load_quic.cc b/src/h2load_quic.cc
new file mode 100644 (file)
index 0000000..7468004
--- /dev/null
@@ -0,0 +1,759 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2019 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "h2load_quic.h"
+
+#include <netinet/udp.h>
+
+#include <iostream>
+
+#ifdef HAVE_LIBNGTCP2_CRYPTO_OPENSSL
+#  include <ngtcp2/ngtcp2_crypto_openssl.h>
+#endif // HAVE_LIBNGTCP2_CRYPTO_OPENSSL
+#ifdef HAVE_LIBNGTCP2_CRYPTO_BORINGSSL
+#  include <ngtcp2/ngtcp2_crypto_boringssl.h>
+#endif // HAVE_LIBNGTCP2_CRYPTO_BORINGSSL
+
+#include <openssl/err.h>
+
+#include "h2load_http3_session.h"
+
+namespace h2load {
+
+namespace {
+auto randgen = util::make_mt19937();
+} // namespace
+
+namespace {
+int handshake_completed(ngtcp2_conn *conn, void *user_data) {
+  auto c = static_cast<Client *>(user_data);
+
+  if (c->quic_handshake_completed() != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Client::quic_handshake_completed() { return connection_made(); }
+
+namespace {
+int recv_stream_data(ngtcp2_conn *conn, uint32_t flags, int64_t stream_id,
+                     uint64_t offset, const uint8_t *data, size_t datalen,
+                     void *user_data, void *stream_user_data) {
+  auto c = static_cast<Client *>(user_data);
+  if (c->quic_recv_stream_data(flags, stream_id, data, datalen) != 0) {
+    // TODO Better to do this gracefully rather than
+    // NGTCP2_ERR_CALLBACK_FAILURE.  Perhaps, call
+    // ngtcp2_conn_write_application_close() ?
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+  return 0;
+}
+} // namespace
+
+int Client::quic_recv_stream_data(uint32_t flags, int64_t stream_id,
+                                  const uint8_t *data, size_t datalen) {
+  if (worker->current_phase == Phase::MAIN_DURATION) {
+    worker->stats.bytes_total += datalen;
+  }
+
+  auto s = static_cast<Http3Session *>(session.get());
+  auto nconsumed = s->read_stream(flags, stream_id, data, datalen);
+  if (nconsumed == -1) {
+    return -1;
+  }
+
+  ngtcp2_conn_extend_max_stream_offset(quic.conn, stream_id, nconsumed);
+  ngtcp2_conn_extend_max_offset(quic.conn, nconsumed);
+
+  return 0;
+}
+
+namespace {
+int acked_stream_data_offset(ngtcp2_conn *conn, int64_t stream_id,
+                             uint64_t offset, uint64_t datalen, void *user_data,
+                             void *stream_user_data) {
+  auto c = static_cast<Client *>(user_data);
+  if (c->quic_acked_stream_data_offset(stream_id, datalen) != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+  return 0;
+}
+} // namespace
+
+int Client::quic_acked_stream_data_offset(int64_t stream_id, size_t datalen) {
+  auto s = static_cast<Http3Session *>(session.get());
+  if (s->add_ack_offset(stream_id, datalen) != 0) {
+    return -1;
+  }
+  return 0;
+}
+
+namespace {
+int stream_close(ngtcp2_conn *conn, uint32_t flags, int64_t stream_id,
+                 uint64_t app_error_code, void *user_data,
+                 void *stream_user_data) {
+  auto c = static_cast<Client *>(user_data);
+
+  if (!(flags & NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET)) {
+    app_error_code = NGHTTP3_H3_NO_ERROR;
+  }
+
+  if (c->quic_stream_close(stream_id, app_error_code) != 0) {
+    return -1;
+  }
+  return 0;
+}
+} // namespace
+
+int Client::quic_stream_close(int64_t stream_id, uint64_t app_error_code) {
+  auto s = static_cast<Http3Session *>(session.get());
+  if (s->close_stream(stream_id, app_error_code) != 0) {
+    return -1;
+  }
+  return 0;
+}
+
+namespace {
+int stream_reset(ngtcp2_conn *conn, int64_t stream_id, uint64_t final_size,
+                 uint64_t app_error_code, void *user_data,
+                 void *stream_user_data) {
+  auto c = static_cast<Client *>(user_data);
+  if (c->quic_stream_reset(stream_id, app_error_code) != 0) {
+    return -1;
+  }
+  return 0;
+}
+} // namespace
+
+int Client::quic_stream_reset(int64_t stream_id, uint64_t app_error_code) {
+  auto s = static_cast<Http3Session *>(session.get());
+  if (s->shutdown_stream_read(stream_id) != 0) {
+    return -1;
+  }
+  return 0;
+}
+
+namespace {
+int stream_stop_sending(ngtcp2_conn *conn, int64_t stream_id,
+                        uint64_t app_error_code, void *user_data,
+                        void *stream_user_data) {
+  auto c = static_cast<Client *>(user_data);
+  if (c->quic_stream_stop_sending(stream_id, app_error_code) != 0) {
+    return -1;
+  }
+  return 0;
+}
+} // namespace
+
+int Client::quic_stream_stop_sending(int64_t stream_id,
+                                     uint64_t app_error_code) {
+  auto s = static_cast<Http3Session *>(session.get());
+  if (s->shutdown_stream_read(stream_id) != 0) {
+    return -1;
+  }
+  return 0;
+}
+
+namespace {
+int extend_max_local_streams_bidi(ngtcp2_conn *conn, uint64_t max_streams,
+                                  void *user_data) {
+  auto c = static_cast<Client *>(user_data);
+
+  if (c->quic_extend_max_local_streams() != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Client::quic_extend_max_local_streams() {
+  auto s = static_cast<Http3Session *>(session.get());
+  if (s->extend_max_local_streams() != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+  return 0;
+}
+
+namespace {
+int get_new_connection_id(ngtcp2_conn *conn, ngtcp2_cid *cid, uint8_t *token,
+                          size_t cidlen, void *user_data) {
+  auto dis = std::uniform_int_distribution<uint8_t>(
+      0, std::numeric_limits<uint8_t>::max());
+  auto f = [&dis]() { return dis(randgen); };
+
+  std::generate_n(cid->data, cidlen, f);
+  cid->datalen = cidlen;
+  std::generate_n(token, NGTCP2_STATELESS_RESET_TOKENLEN, f);
+
+  return 0;
+}
+} // namespace
+
+namespace {
+void debug_log_printf(void *user_data, const char *fmt, ...) {
+  va_list ap;
+
+  va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+  va_end(ap);
+
+  fprintf(stderr, "\n");
+}
+} // namespace
+
+namespace {
+void generate_cid(ngtcp2_cid &dest) {
+  auto dis = std::uniform_int_distribution<uint8_t>(
+      0, std::numeric_limits<uint8_t>::max());
+  dest.datalen = 8;
+  std::generate_n(dest.data, dest.datalen, [&dis]() { return dis(randgen); });
+}
+} // namespace
+
+namespace {
+ngtcp2_tstamp timestamp(struct ev_loop *loop) {
+  return ev_now(loop) * NGTCP2_SECONDS;
+}
+} // namespace
+
+#ifdef HAVE_LIBNGTCP2_CRYPTO_OPENSSL
+namespace {
+int set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
+                           const uint8_t *rx_secret, const uint8_t *tx_secret,
+                           size_t secret_len) {
+  auto c = static_cast<Client *>(SSL_get_app_data(ssl));
+  auto level = ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
+
+  if (c->quic_on_rx_secret(level, rx_secret, secret_len) != 0) {
+    return 0;
+  }
+
+  if (c->quic_on_tx_secret(level, tx_secret, secret_len) != 0) {
+    return 0;
+  }
+
+  return 1;
+}
+} // namespace
+
+namespace {
+int add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
+                       const uint8_t *data, size_t len) {
+  auto c = static_cast<Client *>(SSL_get_app_data(ssl));
+  c->quic_write_client_handshake(
+      ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level), data, len);
+  return 1;
+}
+} // namespace
+
+namespace {
+int flush_flight(SSL *ssl) { return 1; }
+} // namespace
+
+namespace {
+int send_alert(SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert) {
+  auto c = static_cast<Client *>(SSL_get_app_data(ssl));
+  c->quic_set_tls_alert(alert);
+  return 1;
+}
+} // namespace
+
+namespace {
+auto quic_method = SSL_QUIC_METHOD{
+    set_encryption_secrets,
+    add_handshake_data,
+    flush_flight,
+    send_alert,
+};
+} // namespace
+#endif // HAVE_LIBNGTCP2_CRYPTO_OPENSSL
+
+#ifdef HAVE_LIBNGTCP2_CRYPTO_BORINGSSL
+namespace {
+int set_read_secret(SSL *ssl, ssl_encryption_level_t ssl_level,
+                    const SSL_CIPHER *cipher, const uint8_t *secret,
+                    size_t secretlen) {
+  auto c = static_cast<Client *>(SSL_get_app_data(ssl));
+
+  if (c->quic_on_rx_secret(
+          ngtcp2_crypto_boringssl_from_ssl_encryption_level(ssl_level), secret,
+          secretlen) != 0) {
+    return 0;
+  }
+
+  return 1;
+}
+} // namespace
+
+namespace {
+int set_write_secret(SSL *ssl, ssl_encryption_level_t ssl_level,
+                     const SSL_CIPHER *cipher, const uint8_t *secret,
+                     size_t secretlen) {
+  auto c = static_cast<Client *>(SSL_get_app_data(ssl));
+
+  if (c->quic_on_tx_secret(
+          ngtcp2_crypto_boringssl_from_ssl_encryption_level(ssl_level), secret,
+          secretlen) != 0) {
+    return 0;
+  }
+
+  return 1;
+}
+} // namespace
+
+namespace {
+int add_handshake_data(SSL *ssl, ssl_encryption_level_t ssl_level,
+                       const uint8_t *data, size_t len) {
+  auto c = static_cast<Client *>(SSL_get_app_data(ssl));
+  c->quic_write_client_handshake(
+      ngtcp2_crypto_boringssl_from_ssl_encryption_level(ssl_level), data, len);
+  return 1;
+}
+} // namespace
+
+namespace {
+int flush_flight(SSL *ssl) { return 1; }
+} // namespace
+
+namespace {
+int send_alert(SSL *ssl, ssl_encryption_level_t level, uint8_t alert) {
+  auto c = static_cast<Client *>(SSL_get_app_data(ssl));
+  c->quic_set_tls_alert(alert);
+  return 1;
+}
+} // namespace
+
+namespace {
+auto quic_method = SSL_QUIC_METHOD{
+    set_read_secret, set_write_secret, add_handshake_data,
+    flush_flight,    send_alert,
+};
+} // namespace
+#endif // HAVE_LIBNGTCP2_CRYPTO_BORINGSSL
+
+// qlog write callback -- excerpted from ngtcp2/examples/client_base.cc
+namespace {
+void qlog_write_cb(void *user_data, uint32_t flags, const void *data,
+                   size_t datalen) {
+  auto c = static_cast<Client *>(user_data);
+  c->quic_write_qlog(data, datalen);
+}
+} // namespace
+
+void Client::quic_write_qlog(const void *data, size_t datalen) {
+  assert(quic.qlog_file != nullptr);
+  fwrite(data, 1, datalen, quic.qlog_file);
+}
+
+int Client::quic_init(const sockaddr *local_addr, socklen_t local_addrlen,
+                      const sockaddr *remote_addr, socklen_t remote_addrlen) {
+  int rv;
+
+  if (!ssl) {
+    ssl = SSL_new(worker->ssl_ctx);
+
+    SSL_set_app_data(ssl, this);
+    SSL_set_connect_state(ssl);
+    SSL_set_quic_method(ssl, &quic_method);
+    SSL_set_quic_use_legacy_codepoint(ssl, 0);
+  }
+
+  auto callbacks = ngtcp2_callbacks{
+      ngtcp2_crypto_client_initial_cb,
+      nullptr, // recv_client_initial
+      ngtcp2_crypto_recv_crypto_data_cb,
+      h2load::handshake_completed,
+      nullptr, // recv_version_negotiation
+      ngtcp2_crypto_encrypt_cb,
+      ngtcp2_crypto_decrypt_cb,
+      ngtcp2_crypto_hp_mask_cb,
+      h2load::recv_stream_data,
+      h2load::acked_stream_data_offset,
+      nullptr, // stream_open
+      h2load::stream_close,
+      nullptr, // recv_stateless_reset
+      ngtcp2_crypto_recv_retry_cb,
+      h2load::extend_max_local_streams_bidi,
+      nullptr, // extend_max_local_streams_uni
+      nullptr, // rand
+      get_new_connection_id,
+      nullptr, // remove_connection_id
+      ngtcp2_crypto_update_key_cb,
+      nullptr, // path_validation
+      nullptr, // select_preferred_addr
+      h2load::stream_reset,
+      nullptr, // extend_max_remote_streams_bidi
+      nullptr, // extend_max_remote_streams_uni
+      nullptr, // extend_max_stream_data
+      nullptr, // dcid_status
+      nullptr, // handshake_confirmed
+      nullptr, // recv_new_token
+      ngtcp2_crypto_delete_crypto_aead_ctx_cb,
+      ngtcp2_crypto_delete_crypto_cipher_ctx_cb,
+      nullptr, // recv_datagram
+      nullptr, // ack_datagram
+      nullptr, // lost_datagram
+      nullptr, // get_path_challenge_data
+      h2load::stream_stop_sending,
+  };
+
+  ngtcp2_cid scid, dcid;
+  generate_cid(scid);
+  generate_cid(dcid);
+
+  auto config = worker->config;
+
+  ngtcp2_settings settings;
+  ngtcp2_settings_default(&settings);
+  if (config->verbose) {
+    settings.log_printf = debug_log_printf;
+  }
+  settings.initial_ts = timestamp(worker->loop);
+  if (!config->qlog_file_base.empty()) {
+    assert(quic.qlog_file == nullptr);
+    auto path = config->qlog_file_base;
+    path += '.';
+    path += util::utos(worker->id);
+    path += '.';
+    path += util::utos(id);
+    path += ".qlog";
+    quic.qlog_file = fopen(path.c_str(), "w");
+    if (quic.qlog_file == nullptr) {
+      std::cerr << "Failed to open a qlog file: " << path << std::endl;
+      return -1;
+    }
+    settings.qlog.write = qlog_write_cb;
+  }
+  if (config->max_udp_payload_size) {
+    settings.max_udp_payload_size = config->max_udp_payload_size;
+    settings.no_udp_payload_size_shaping = 1;
+  }
+
+  ngtcp2_transport_params params;
+  ngtcp2_transport_params_default(&params);
+  auto max_stream_data =
+      std::min((1 << 26) - 1, (1 << config->window_bits) - 1);
+  params.initial_max_stream_data_bidi_local = max_stream_data;
+  params.initial_max_stream_data_uni = max_stream_data;
+  params.initial_max_data = (1 << config->connection_window_bits) - 1;
+  params.initial_max_streams_bidi = 0;
+  params.initial_max_streams_uni = 100;
+  params.max_idle_timeout = 30 * NGTCP2_SECONDS;
+
+  auto path = ngtcp2_path{
+      {local_addrlen, const_cast<sockaddr *>(local_addr)},
+      {remote_addrlen, const_cast<sockaddr *>(remote_addr)},
+  };
+
+  assert(config->npn_list.size());
+
+  uint32_t quic_version;
+
+  if (config->npn_list[0] == NGHTTP3_ALPN_H3) {
+    quic_version = NGTCP2_PROTO_VER_V1;
+  } else {
+    quic_version = NGTCP2_PROTO_VER_MIN;
+  }
+
+  rv = ngtcp2_conn_client_new(&quic.conn, &dcid, &scid, &path, quic_version,
+                              &callbacks, &settings, &params, nullptr, this);
+  if (rv != 0) {
+    return -1;
+  }
+
+  ngtcp2_conn_set_tls_native_handle(quic.conn, ssl);
+
+  return 0;
+}
+
+void Client::quic_free() {
+  ngtcp2_conn_del(quic.conn);
+  if (quic.qlog_file != nullptr) {
+    fclose(quic.qlog_file);
+    quic.qlog_file = nullptr;
+  }
+}
+
+void Client::quic_close_connection() {
+  if (!quic.conn) {
+    return;
+  }
+
+  std::array<uint8_t, NGTCP2_MAX_UDP_PAYLOAD_SIZE> buf;
+  ngtcp2_ssize nwrite;
+  ngtcp2_path_storage ps;
+  ngtcp2_path_storage_zero(&ps);
+
+  switch (quic.last_error.type) {
+  case quic::ErrorType::TransportVersionNegotiation:
+    return;
+  case quic::ErrorType::Transport:
+    nwrite = ngtcp2_conn_write_connection_close(
+        quic.conn, &ps.path, nullptr, buf.data(), buf.size(),
+        quic.last_error.code, timestamp(worker->loop));
+    break;
+  case quic::ErrorType::Application:
+    nwrite = ngtcp2_conn_write_application_close(
+        quic.conn, &ps.path, nullptr, buf.data(), buf.size(),
+        quic.last_error.code, timestamp(worker->loop));
+    break;
+  default:
+    assert(0);
+    abort();
+  }
+
+  if (nwrite < 0) {
+    return;
+  }
+
+  write_udp(reinterpret_cast<sockaddr *>(ps.path.remote.addr),
+            ps.path.remote.addrlen, buf.data(), nwrite, 0);
+}
+
+int Client::quic_on_rx_secret(ngtcp2_crypto_level level, const uint8_t *secret,
+                              size_t secretlen) {
+  if (ngtcp2_crypto_derive_and_install_rx_key(quic.conn, nullptr, nullptr,
+                                              nullptr, level, secret,
+                                              secretlen) != 0) {
+    std::cerr << "ngtcp2_crypto_derive_and_install_rx_key() failed"
+              << std::endl;
+    return -1;
+  }
+
+  if (level == NGTCP2_CRYPTO_LEVEL_APPLICATION) {
+    auto s = std::make_unique<Http3Session>(this);
+    if (s->init_conn() == -1) {
+      return -1;
+    }
+    session = std::move(s);
+  }
+
+  return 0;
+}
+
+int Client::quic_on_tx_secret(ngtcp2_crypto_level level, const uint8_t *secret,
+                              size_t secretlen) {
+  if (ngtcp2_crypto_derive_and_install_tx_key(quic.conn, nullptr, nullptr,
+                                              nullptr, level, secret,
+                                              secretlen) != 0) {
+    std::cerr << "ngtcp2_crypto_derive_and_install_tx_key() failed"
+              << std::endl;
+    return -1;
+  }
+
+  return 0;
+}
+
+void Client::quic_set_tls_alert(uint8_t alert) {
+  quic.last_error = quic::err_transport_tls(alert);
+}
+
+void Client::quic_write_client_handshake(ngtcp2_crypto_level level,
+                                         const uint8_t *data, size_t datalen) {
+  assert(level < 2);
+
+  ngtcp2_conn_submit_crypto_data(quic.conn, level, data, datalen);
+}
+
+void quic_pkt_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
+  auto c = static_cast<Client *>(w->data);
+
+  if (c->quic_pkt_timeout() != 0) {
+    c->fail();
+    c->worker->free_client(c);
+    delete c;
+    return;
+  }
+}
+
+int Client::quic_pkt_timeout() {
+  int rv;
+  auto now = timestamp(worker->loop);
+
+  rv = ngtcp2_conn_handle_expiry(quic.conn, now);
+  if (rv != 0) {
+    quic.last_error = quic::err_transport(NGTCP2_ERR_INTERNAL);
+    return -1;
+  }
+
+  return write_quic();
+}
+
+void Client::quic_restart_pkt_timer() {
+  auto expiry = ngtcp2_conn_get_expiry(quic.conn);
+  auto now = timestamp(worker->loop);
+  auto t = expiry > now ? static_cast<ev_tstamp>(expiry - now) / NGTCP2_SECONDS
+                        : 1e-9;
+  quic.pkt_timer.repeat = t;
+  ev_timer_again(worker->loop, &quic.pkt_timer);
+}
+
+int Client::read_quic() {
+  std::array<uint8_t, 65536> buf;
+  sockaddr_union su;
+  socklen_t addrlen = sizeof(su);
+  int rv;
+  size_t pktcnt = 0;
+  ngtcp2_pkt_info pi{};
+
+  for (;;) {
+    auto nread =
+        recvfrom(fd, buf.data(), buf.size(), MSG_DONTWAIT, &su.sa, &addrlen);
+    if (nread == -1) {
+      return 0;
+    }
+
+    assert(quic.conn);
+
+    ++worker->stats.udp_dgram_recv;
+
+    auto path = ngtcp2_path{
+        {local_addr.len, &local_addr.su.sa},
+        {addrlen, &su.sa},
+    };
+
+    rv = ngtcp2_conn_read_pkt(quic.conn, &path, &pi, buf.data(), nread,
+                              timestamp(worker->loop));
+    if (rv != 0) {
+      std::cerr << "ngtcp2_conn_read_pkt: " << ngtcp2_strerror(rv) << std::endl;
+      return -1;
+    }
+
+    if (++pktcnt == 100) {
+      break;
+    }
+  }
+
+  return 0;
+}
+
+int Client::write_quic() {
+  ev_io_stop(worker->loop, &wev);
+
+  if (quic.close_requested) {
+    return -1;
+  }
+
+  std::array<nghttp3_vec, 16> vec;
+  size_t pktcnt = 0;
+  auto max_udp_payload_size =
+      ngtcp2_conn_get_path_max_udp_payload_size(quic.conn);
+  size_t max_pktcnt =
+#ifdef UDP_SEGMENT
+      worker->config->no_udp_gso
+          ? 1
+          : std::min(static_cast<size_t>(10),
+                     static_cast<size_t>(64_k / max_udp_payload_size));
+#else  // !UDP_SEGMENT
+      1;
+#endif // !UDP_SEGMENT
+  std::array<uint8_t, 64_k> buf;
+  uint8_t *bufpos = buf.data();
+  ngtcp2_path_storage ps;
+
+  ngtcp2_path_storage_zero(&ps);
+
+  auto s = static_cast<Http3Session *>(session.get());
+
+  for (;;) {
+    int64_t stream_id = -1;
+    int fin = 0;
+    ssize_t sveccnt = 0;
+
+    if (session && ngtcp2_conn_get_max_data_left(quic.conn)) {
+      sveccnt = s->write_stream(stream_id, fin, vec.data(), vec.size());
+      if (sveccnt == -1) {
+        return -1;
+      }
+    }
+
+    ngtcp2_ssize ndatalen;
+    auto v = vec.data();
+    auto vcnt = static_cast<size_t>(sveccnt);
+
+    uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_MORE;
+    if (fin) {
+      flags |= NGTCP2_WRITE_STREAM_FLAG_FIN;
+    }
+
+    auto nwrite = ngtcp2_conn_writev_stream(
+        quic.conn, &ps.path, nullptr, bufpos, max_udp_payload_size, &ndatalen,
+        flags, stream_id, reinterpret_cast<const ngtcp2_vec *>(v), vcnt,
+        timestamp(worker->loop));
+    if (nwrite < 0) {
+      switch (nwrite) {
+      case NGTCP2_ERR_STREAM_DATA_BLOCKED:
+        assert(ndatalen == -1);
+        if (s->block_stream(stream_id) != 0) {
+          return -1;
+        }
+        continue;
+      case NGTCP2_ERR_STREAM_SHUT_WR:
+        assert(ndatalen == -1);
+        if (s->shutdown_stream_write(stream_id) != 0) {
+          return -1;
+        }
+        continue;
+      case NGTCP2_ERR_WRITE_MORE:
+        assert(ndatalen >= 0);
+        if (s->add_write_offset(stream_id, ndatalen) != 0) {
+          return -1;
+        }
+        continue;
+      }
+
+      quic.last_error = quic::err_transport(nwrite);
+      return -1;
+    } else if (ndatalen >= 0 && s->add_write_offset(stream_id, ndatalen) != 0) {
+      return -1;
+    }
+
+    quic_restart_pkt_timer();
+
+    if (nwrite == 0) {
+      if (bufpos - buf.data()) {
+        write_udp(ps.path.remote.addr, ps.path.remote.addrlen, buf.data(),
+                  bufpos - buf.data(), max_udp_payload_size);
+      }
+      return 0;
+    }
+
+    bufpos += nwrite;
+
+    // Assume that the path does not change.
+    if (++pktcnt == max_pktcnt ||
+        static_cast<size_t>(nwrite) < max_udp_payload_size) {
+      write_udp(ps.path.remote.addr, ps.path.remote.addrlen, buf.data(),
+                bufpos - buf.data(), max_udp_payload_size);
+      signal_write();
+      return 0;
+    }
+  }
+}
+
+} // namespace h2load
diff --git a/src/h2load_quic.h b/src/h2load_quic.h
new file mode 100644 (file)
index 0000000..225f00f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2019 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef H2LOAD_QUIC_H
+#define H2LOAD_QUIC_H
+
+#include "nghttp2_config.h"
+
+#include <ev.h>
+
+#include "h2load.h"
+
+namespace h2load {
+void quic_pkt_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents);
+} // namespace h2load
+
+#endif // H2LOAD_QUIC_H
index c5b596f..64d700f 100644 (file)
@@ -1841,6 +1841,53 @@ StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
                    query);
 }
 
+StringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
+                               const StringRef &query) {
+  // First, decode %XX for unreserved characters and ':', then do
+  // http2::path_join
+
+  // We won't find %XX if length is less than 3.
+  if (path.size() < 3 ||
+      std::find(std::begin(path), std::end(path), '%') == std::end(path)) {
+    return path_join(balloc, StringRef{}, StringRef{}, path, query);
+  }
+
+  // includes last terminal NULL.
+  auto result = make_byte_ref(balloc, path.size() + 1);
+  auto p = result.base;
+
+  auto it = std::begin(path);
+  for (; it + 2 < std::end(path);) {
+    if (*it == '%') {
+      if (util::is_hex_digit(*(it + 1)) && util::is_hex_digit(*(it + 2))) {
+        auto c =
+            (util::hex_to_uint(*(it + 1)) << 4) + util::hex_to_uint(*(it + 2));
+        if (util::in_rfc3986_unreserved_chars(c) || c == ':') {
+          *p++ = c;
+
+          it += 3;
+
+          continue;
+        }
+        *p++ = '%';
+        *p++ = util::upcase(*(it + 1));
+        *p++ = util::upcase(*(it + 2));
+
+        it += 3;
+
+        continue;
+      }
+    }
+    *p++ = *it++;
+  }
+
+  p = std::copy(it, std::end(path), p);
+  *p = '\0';
+
+  return path_join(balloc, StringRef{}, StringRef{}, StringRef{result.base, p},
+                   query);
+}
+
 std::string normalize_path(const StringRef &path, const StringRef &query) {
   BlockAllocator balloc(1024, 1024);
 
index b0b1065..f5c0713 100644 (file)
@@ -410,6 +410,12 @@ StringRef to_method_string(int method_token);
 StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
                          const StringRef &query);
 
+// normalize_path_colon is like normalize_path, but it additionally
+// does percent-decoding %3A in order to workaround the issue that ':'
+// cannot be included in backend pattern.
+StringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
+                               const StringRef &query);
+
 std::string normalize_path(const StringRef &path, const StringRef &query);
 
 StringRef rewrite_clean_path(BlockAllocator &balloc, const StringRef &src);
diff --git a/src/http3.cc b/src/http3.cc
new file mode 100644 (file)
index 0000000..61134ad
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "http3.h"
+
+namespace nghttp2 {
+
+namespace http3 {
+
+namespace {
+nghttp3_nv make_nv_internal(const std::string &name, const std::string &value,
+                            bool never_index, uint8_t nv_flags) {
+  uint8_t flags;
+
+  flags = nv_flags |
+          (never_index ? NGHTTP3_NV_FLAG_NEVER_INDEX : NGHTTP3_NV_FLAG_NONE);
+
+  return {(uint8_t *)name.c_str(), (uint8_t *)value.c_str(), name.size(),
+          value.size(), flags};
+}
+} // namespace
+
+namespace {
+nghttp3_nv make_nv_internal(const StringRef &name, const StringRef &value,
+                            bool never_index, uint8_t nv_flags) {
+  uint8_t flags;
+
+  flags = nv_flags |
+          (never_index ? NGHTTP3_NV_FLAG_NEVER_INDEX : NGHTTP3_NV_FLAG_NONE);
+
+  return {(uint8_t *)name.c_str(), (uint8_t *)value.c_str(), name.size(),
+          value.size(), flags};
+}
+} // namespace
+
+nghttp3_nv make_nv(const std::string &name, const std::string &value,
+                   bool never_index) {
+  return make_nv_internal(name, value, never_index, NGHTTP3_NV_FLAG_NONE);
+}
+
+nghttp3_nv make_nv(const StringRef &name, const StringRef &value,
+                   bool never_index) {
+  return make_nv_internal(name, value, never_index, NGHTTP3_NV_FLAG_NONE);
+}
+
+nghttp3_nv make_nv_nocopy(const std::string &name, const std::string &value,
+                          bool never_index) {
+  return make_nv_internal(name, value, never_index,
+                          NGHTTP3_NV_FLAG_NO_COPY_NAME |
+                              NGHTTP3_NV_FLAG_NO_COPY_VALUE);
+}
+
+nghttp3_nv make_nv_nocopy(const StringRef &name, const StringRef &value,
+                          bool never_index) {
+  return make_nv_internal(name, value, never_index,
+                          NGHTTP3_NV_FLAG_NO_COPY_NAME |
+                              NGHTTP3_NV_FLAG_NO_COPY_VALUE);
+}
+
+namespace {
+void copy_headers_to_nva_internal(std::vector<nghttp3_nv> &nva,
+                                  const HeaderRefs &headers, uint8_t nv_flags,
+                                  uint32_t flags) {
+  auto it_forwarded = std::end(headers);
+  auto it_xff = std::end(headers);
+  auto it_xfp = std::end(headers);
+  auto it_via = std::end(headers);
+
+  for (auto it = std::begin(headers); it != std::end(headers); ++it) {
+    auto kv = &(*it);
+    if (kv->name.empty() || kv->name[0] == ':') {
+      continue;
+    }
+    switch (kv->token) {
+    case http2::HD_COOKIE:
+    case http2::HD_CONNECTION:
+    case http2::HD_HOST:
+    case http2::HD_HTTP2_SETTINGS:
+    case http2::HD_KEEP_ALIVE:
+    case http2::HD_PROXY_CONNECTION:
+    case http2::HD_SERVER:
+    case http2::HD_TE:
+    case http2::HD_TRANSFER_ENCODING:
+    case http2::HD_UPGRADE:
+      continue;
+    case http2::HD_EARLY_DATA:
+      if (flags & http2::HDOP_STRIP_EARLY_DATA) {
+        continue;
+      }
+      break;
+    case http2::HD_SEC_WEBSOCKET_ACCEPT:
+      if (flags & http2::HDOP_STRIP_SEC_WEBSOCKET_ACCEPT) {
+        continue;
+      }
+      break;
+    case http2::HD_SEC_WEBSOCKET_KEY:
+      if (flags & http2::HDOP_STRIP_SEC_WEBSOCKET_KEY) {
+        continue;
+      }
+      break;
+    case http2::HD_FORWARDED:
+      if (flags & http2::HDOP_STRIP_FORWARDED) {
+        continue;
+      }
+
+      if (it_forwarded == std::end(headers)) {
+        it_forwarded = it;
+        continue;
+      }
+
+      kv = &(*it_forwarded);
+      it_forwarded = it;
+      break;
+    case http2::HD_X_FORWARDED_FOR:
+      if (flags & http2::HDOP_STRIP_X_FORWARDED_FOR) {
+        continue;
+      }
+
+      if (it_xff == std::end(headers)) {
+        it_xff = it;
+        continue;
+      }
+
+      kv = &(*it_xff);
+      it_xff = it;
+      break;
+    case http2::HD_X_FORWARDED_PROTO:
+      if (flags & http2::HDOP_STRIP_X_FORWARDED_PROTO) {
+        continue;
+      }
+
+      if (it_xfp == std::end(headers)) {
+        it_xfp = it;
+        continue;
+      }
+
+      kv = &(*it_xfp);
+      it_xfp = it;
+      break;
+    case http2::HD_VIA:
+      if (flags & http2::HDOP_STRIP_VIA) {
+        continue;
+      }
+
+      if (it_via == std::end(headers)) {
+        it_via = it;
+        continue;
+      }
+
+      kv = &(*it_via);
+      it_via = it;
+      break;
+    }
+    nva.push_back(
+        make_nv_internal(kv->name, kv->value, kv->no_index, nv_flags));
+  }
+}
+} // namespace
+
+void copy_headers_to_nva(std::vector<nghttp3_nv> &nva,
+                         const HeaderRefs &headers, uint32_t flags) {
+  copy_headers_to_nva_internal(nva, headers, NGHTTP3_NV_FLAG_NONE, flags);
+}
+
+void copy_headers_to_nva_nocopy(std::vector<nghttp3_nv> &nva,
+                                const HeaderRefs &headers, uint32_t flags) {
+  copy_headers_to_nva_internal(
+      nva, headers,
+      NGHTTP3_NV_FLAG_NO_COPY_NAME | NGHTTP3_NV_FLAG_NO_COPY_VALUE, flags);
+}
+
+int check_nv(const uint8_t *name, size_t namelen, const uint8_t *value,
+             size_t valuelen) {
+  if (!nghttp3_check_header_name(name, namelen)) {
+    return 0;
+  }
+  if (!nghttp3_check_header_value(value, valuelen)) {
+    return 0;
+  }
+  return 1;
+}
+
+} // namespace http3
+
+} // namespace nghttp2
diff --git a/src/http3.h b/src/http3.h
new file mode 100644 (file)
index 0000000..81ee0d7
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef HTTP3_H
+#define HTTP3_H
+
+#include "nghttp2_config.h"
+
+#include <cstring>
+#include <string>
+#include <vector>
+
+#include <nghttp3/nghttp3.h>
+
+#include "http2.h"
+#include "template.h"
+
+namespace nghttp2 {
+
+namespace http3 {
+
+// Creates nghttp3_nv using |name| and |value| and returns it. The
+// returned value only references the data pointer to name.c_str() and
+// value.c_str().  If |no_index| is true, nghttp3_nv flags member has
+// NGHTTP3_NV_FLAG_NEVER_INDEX flag set.
+nghttp3_nv make_nv(const std::string &name, const std::string &value,
+                   bool never_index = false);
+
+nghttp3_nv make_nv(const StringRef &name, const StringRef &value,
+                   bool never_index = false);
+
+nghttp3_nv make_nv_nocopy(const std::string &name, const std::string &value,
+                          bool never_index = false);
+
+nghttp3_nv make_nv_nocopy(const StringRef &name, const StringRef &value,
+                          bool never_index = false);
+
+// Create nghttp3_nv from string literal |name| and |value|.
+template <size_t N, size_t M>
+constexpr nghttp3_nv make_nv_ll(const char (&name)[N], const char (&value)[M]) {
+  return {(uint8_t *)name, (uint8_t *)value, N - 1, M - 1,
+          NGHTTP3_NV_FLAG_NO_COPY_NAME | NGHTTP3_NV_FLAG_NO_COPY_VALUE};
+}
+
+// Create nghttp3_nv from string literal |name| and c-string |value|.
+template <size_t N>
+nghttp3_nv make_nv_lc(const char (&name)[N], const char *value) {
+  return {(uint8_t *)name, (uint8_t *)value, N - 1, strlen(value),
+          NGHTTP3_NV_FLAG_NO_COPY_NAME};
+}
+
+template <size_t N>
+nghttp3_nv make_nv_lc_nocopy(const char (&name)[N], const char *value) {
+  return {(uint8_t *)name, (uint8_t *)value, N - 1, strlen(value),
+          NGHTTP3_NV_FLAG_NO_COPY_NAME | NGHTTP3_NV_FLAG_NO_COPY_VALUE};
+}
+
+// Create nghttp3_nv from string literal |name| and std::string
+// |value|.
+template <size_t N>
+nghttp3_nv make_nv_ls(const char (&name)[N], const std::string &value) {
+  return {(uint8_t *)name, (uint8_t *)value.c_str(), N - 1, value.size(),
+          NGHTTP3_NV_FLAG_NO_COPY_NAME};
+}
+
+template <size_t N>
+nghttp3_nv make_nv_ls_nocopy(const char (&name)[N], const std::string &value) {
+  return {(uint8_t *)name, (uint8_t *)value.c_str(), N - 1, value.size(),
+          NGHTTP3_NV_FLAG_NO_COPY_NAME | NGHTTP3_NV_FLAG_NO_COPY_VALUE};
+}
+
+template <size_t N>
+nghttp3_nv make_nv_ls_nocopy(const char (&name)[N], const StringRef &value) {
+  return {(uint8_t *)name, (uint8_t *)value.c_str(), N - 1, value.size(),
+          NGHTTP3_NV_FLAG_NO_COPY_NAME | NGHTTP3_NV_FLAG_NO_COPY_VALUE};
+}
+
+// Appends headers in |headers| to |nv|.  |headers| must be indexed
+// before this call (its element's token field is assigned).  Certain
+// headers, including disallowed headers in HTTP/3 spec and headers
+// which require special handling (i.e. via), are not copied.  |flags|
+// is one or more of HeaderBuildOp flags.  They tell function that
+// certain header fields should not be added.
+void copy_headers_to_nva(std::vector<nghttp3_nv> &nva,
+                         const HeaderRefs &headers, uint32_t flags);
+
+// Just like copy_headers_to_nva(), but this adds
+// NGHTTP3_NV_FLAG_NO_COPY_NAME and NGHTTP3_NV_FLAG_NO_COPY_VALUE.
+void copy_headers_to_nva_nocopy(std::vector<nghttp3_nv> &nva,
+                                const HeaderRefs &headers, uint32_t flags);
+
+// Checks the header name/value pair using nghttp3_check_header_name()
+// and nghttp3_check_header_value(). If both function returns nonzero,
+// this function returns nonzero.
+int check_nv(const uint8_t *name, size_t namelen, const uint8_t *value,
+             size_t valuelen);
+
+} // namespace http3
+
+} // namespace nghttp2
+
+#endif // HTTP3_H
index 3b63438..1745096 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -199,8 +199,6 @@ am__define_uniq_tagged_files = \
   unique=`for i in $$list; do \
     if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
   done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
 am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
@@ -217,11 +215,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -240,8 +241,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -252,9 +256,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -263,9 +270,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -303,8 +319,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -501,7 +518,6 @@ cscopelist-am: $(am__tagged_files)
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
index 59ba9b2..7257914 100644 (file)
@@ -51,8 +51,8 @@ public:
   // Returns content-length.  -1 if it is unknown.
   int64_t content_length() const;
 
-  // Returns the response header fields.  The pusedo header fields,
-  // which start with colon (:), are exluced from this list.
+  // Returns the response header fields.  The pseudo header fields,
+  // which start with colon (:), are excluded from this list.
   const header_map &header() const;
 
   // Application must not call this directly.
@@ -107,8 +107,8 @@ public:
   // Returns request URI, split into components.
   const uri_ref &uri() const;
 
-  // Returns request header fields.  The pusedo header fields, which
-  // start with colon (:), are exluced from this list.
+  // Returns request header fields.  The pseudo header fields, which
+  // start with colon (:), are excluded from this list.
   const header_map &header() const;
 
   // Application must not call this directly.
index d4ec489..651af69 100644 (file)
@@ -42,8 +42,8 @@ public:
   request();
   ~request();
 
-  // Returns request header fields.  The pusedo header fields, which
-  // start with colon (:), are exluced from this list.
+  // Returns request header fields.  The pseudo header fields, which
+  // start with colon (:), are excluded from this list.
   const header_map &header() const;
 
   // Returns method (e.g., GET).
index f0e24b8..7a7f2e9 100644 (file)
@@ -72,7 +72,7 @@ template <size_t N> struct Memchunk {
 };
 
 template <typename T> struct Pool {
-  Pool() : pool(nullptr), freelist(nullptr), poolsize(0) {}
+  Pool() : pool(nullptr), freelist(nullptr), poolsize(0), freelistsize(0) {}
   ~Pool() { clear(); }
   T *get() {
     if (freelist) {
@@ -80,6 +80,7 @@ template <typename T> struct Pool {
       freelist = freelist->next;
       m->next = nullptr;
       m->reset();
+      freelistsize -= T::size;
       return m;
     }
 
@@ -90,9 +91,11 @@ template <typename T> struct Pool {
   void recycle(T *m) {
     m->next = freelist;
     freelist = m;
+    freelistsize += T::size;
   }
   void clear() {
     freelist = nullptr;
+    freelistsize = 0;
     for (auto p = pool; p;) {
       auto knext = p->knext;
       delete p;
@@ -105,17 +108,27 @@ template <typename T> struct Pool {
   T *pool;
   T *freelist;
   size_t poolsize;
+  size_t freelistsize;
 };
 
 template <typename Memchunk> struct Memchunks {
   Memchunks(Pool<Memchunk> *pool)
-      : pool(pool), head(nullptr), tail(nullptr), len(0) {}
+      : pool(pool),
+        head(nullptr),
+        tail(nullptr),
+        len(0),
+        mark(nullptr),
+        mark_pos(nullptr),
+        mark_offset(0) {}
   Memchunks(const Memchunks &) = delete;
   Memchunks(Memchunks &&other) noexcept
       : pool{other.pool}, // keep other.pool
         head{std::exchange(other.head, nullptr)},
         tail{std::exchange(other.tail, nullptr)},
-        len{std::exchange(other.len, 0)} {}
+        len{std::exchange(other.len, 0)},
+        mark{std::exchange(other.mark, nullptr)},
+        mark_pos{std::exchange(other.mark_pos, nullptr)},
+        mark_offset{std::exchange(other.mark_offset, 0)} {}
   Memchunks &operator=(const Memchunks &) = delete;
   Memchunks &operator=(Memchunks &&other) noexcept {
     if (this == &other) {
@@ -128,6 +141,9 @@ template <typename Memchunk> struct Memchunks {
     head = std::exchange(other.head, nullptr);
     tail = std::exchange(other.tail, nullptr);
     len = std::exchange(other.len, 0);
+    mark = std::exchange(other.mark, nullptr);
+    mark_pos = std::exchange(other.mark_pos, nullptr);
+    mark_offset = std::exchange(other.mark_offset, 0);
 
     return *this;
   }
@@ -196,6 +212,8 @@ template <typename Memchunk> struct Memchunks {
     return len;
   }
   size_t remove(void *dest, size_t count) {
+    assert(mark == nullptr);
+
     if (!tail || count == 0) {
       return 0;
     }
@@ -227,6 +245,8 @@ template <typename Memchunk> struct Memchunks {
     return first - static_cast<uint8_t *>(dest);
   }
   size_t remove(Memchunks &dest, size_t count) {
+    assert(mark == nullptr);
+
     if (!tail || count == 0) {
       return 0;
     }
@@ -258,6 +278,7 @@ template <typename Memchunk> struct Memchunks {
   }
   size_t remove(Memchunks &dest) {
     assert(pool == dest.pool);
+    assert(mark == nullptr);
 
     if (head == nullptr) {
       return 0;
@@ -280,6 +301,8 @@ template <typename Memchunk> struct Memchunks {
     return n;
   }
   size_t drain(size_t count) {
+    assert(mark == nullptr);
+
     auto ndata = count;
     auto m = head;
     while (m) {
@@ -301,6 +324,38 @@ template <typename Memchunk> struct Memchunks {
     }
     return ndata - count;
   }
+  size_t drain_mark(size_t count) {
+    auto ndata = count;
+    auto m = head;
+    while (m) {
+      auto next = m->next;
+      auto n = std::min(count, m->len());
+      m->pos += n;
+      count -= n;
+      len -= n;
+      mark_offset -= n;
+
+      if (m->len() > 0) {
+        assert(mark != m || m->pos <= mark_pos);
+        break;
+      }
+      if (mark == m) {
+        assert(m->pos <= mark_pos);
+
+        mark = nullptr;
+        mark_pos = nullptr;
+        mark_offset = 0;
+      }
+
+      pool->recycle(m);
+      m = next;
+    }
+    head = m;
+    if (head == nullptr) {
+      tail = nullptr;
+    }
+    return ndata - count;
+  }
   int riovec(struct iovec *iov, int iovcnt) const {
     if (!head) {
       return 0;
@@ -313,7 +368,41 @@ template <typename Memchunk> struct Memchunks {
     }
     return i;
   }
+  int riovec_mark(struct iovec *iov, int iovcnt) {
+    if (!head || iovcnt == 0) {
+      return 0;
+    }
+
+    int i = 0;
+    Memchunk *m;
+    if (mark) {
+      if (mark_pos != mark->last) {
+        iov[0].iov_base = mark_pos;
+        iov[0].iov_len = mark->len() - (mark_pos - mark->pos);
+
+        mark_pos = mark->last;
+        mark_offset += iov[0].iov_len;
+        i = 1;
+      }
+      m = mark->next;
+    } else {
+      i = 0;
+      m = head;
+    }
+
+    for (; i < iovcnt && m; ++i, m = m->next) {
+      iov[i].iov_base = m->pos;
+      iov[i].iov_len = m->len();
+
+      mark = m;
+      mark_pos = m->last;
+      mark_offset += m->len();
+    }
+
+    return i;
+  }
   size_t rleft() const { return len; }
+  size_t rleft_mark() const { return len - mark_offset; }
   void reset() {
     for (auto m = head; m;) {
       auto next = m->next;
@@ -321,12 +410,17 @@ template <typename Memchunk> struct Memchunks {
       m = next;
     }
     len = 0;
-    head = tail = nullptr;
+    head = tail = mark = nullptr;
+    mark_pos = nullptr;
+    mark_offset = 0;
   }
 
   Pool<Memchunk> *pool;
   Memchunk *head, *tail;
   size_t len;
+  Memchunk *mark;
+  uint8_t *mark_pos;
+  size_t mark_offset;
 };
 
 // Wrapper around Memchunks to offer "peeking" functionality.
index 81e7ebe..5d62bae 100644 (file)
@@ -198,11 +198,11 @@ StringRef Request::get_real_host() const {
 
 uint16_t Request::get_real_port() const {
   auto scheme = get_real_scheme();
-  return config.host_override.empty()
-             ? util::has_uri_field(u, UF_PORT) ? u.port
-                                               : scheme == "https" ? 443 : 80
-             : config.port_override == 0 ? scheme == "https" ? 443 : 80
-                                         : config.port_override;
+  return config.host_override.empty() ? util::has_uri_field(u, UF_PORT) ? u.port
+                                        : scheme == "https"             ? 443
+                                                                        : 80
+         : config.port_override == 0  ? scheme == "https" ? 443 : 80
+                                      : config.port_override;
 }
 
 void Request::init_html_parser() {
@@ -1681,8 +1681,9 @@ void update_html_parser(HttpClient *client, Request *req, const uint8_t *data,
       continue;
     }
 
-    auto link_port =
-        util::has_uri_field(u, UF_PORT) ? u.port : scheme == "https" ? 443 : 80;
+    auto link_port = util::has_uri_field(u, UF_PORT) ? u.port
+                     : scheme == "https"             ? 443
+                                                     : 80;
 
     if (port != link_port) {
       continue;
@@ -2267,7 +2268,7 @@ int communicate(
   auto loop = EV_DEFAULT;
   SSL_CTX *ssl_ctx = nullptr;
   if (scheme == "https") {
-    ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+    ssl_ctx = SSL_CTX_new(TLS_client_method());
     if (!ssl_ctx) {
       std::cerr << "[ERROR] Failed to create SSL_CTX: "
                 << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
diff --git a/src/quic.cc b/src/quic.cc
new file mode 100644 (file)
index 0000000..1c68a5b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2019 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "quic.h"
+
+#include <cassert>
+
+#include <ngtcp2/ngtcp2.h>
+#include <nghttp3/nghttp3.h>
+
+#include "template.h"
+
+using namespace nghttp2;
+
+namespace quic {
+
+Error err_transport(int liberr) {
+  if (liberr == NGTCP2_ERR_RECV_VERSION_NEGOTIATION) {
+    return {ErrorType::TransportVersionNegotiation, 0};
+  }
+  return {ErrorType::Transport,
+          ngtcp2_err_infer_quic_transport_error_code(liberr)};
+}
+
+Error err_transport_idle_timeout() {
+  return {ErrorType::TransportIdleTimeout, 0};
+}
+
+Error err_transport_tls(int alert) {
+  return {ErrorType::Transport, ngtcp2_err_infer_quic_transport_error_code(
+                                    NGTCP2_CRYPTO_ERROR | alert)};
+}
+
+Error err_application(int liberr) {
+  return {ErrorType::Application,
+          nghttp3_err_infer_quic_app_error_code(liberr)};
+}
+
+} // namespace quic
diff --git a/src/quic.h b/src/quic.h
new file mode 100644 (file)
index 0000000..d72ae1f
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2019 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef QUIC_H
+#define QUIC_H
+
+#include "nghttp2_config.h"
+
+#include "stdint.h"
+
+namespace quic {
+
+enum class ErrorType {
+  Transport,
+  TransportVersionNegotiation,
+  TransportIdleTimeout,
+  Application,
+};
+
+struct Error {
+  Error(ErrorType type, uint64_t code) : type(type), code(code) {}
+  Error() : type(ErrorType::Transport), code(0) {}
+
+  ErrorType type;
+  uint64_t code;
+};
+
+Error err_transport(int liberr);
+Error err_transport_idle_timeout();
+Error err_transport_tls(int alert);
+Error err_application(int liberr);
+
+} // namespace quic
+
+#endif // QUIC_H
index 3cf3816..53b3ff0 100644 (file)
@@ -135,6 +135,8 @@ int main(int argc, char *argv[]) {
                    shrpx::test_shrpx_http_create_via_header_value) ||
       !CU_add_test(pSuite, "http_create_affinity_cookie",
                    shrpx::test_shrpx_http_create_affinity_cookie) ||
+      !CU_add_test(pSuite, "http_create_atlsvc_header_field_value",
+                   shrpx::test_shrpx_http_create_altsvc_header_value) ||
       !CU_add_test(pSuite, "router_match", shrpx::test_shrpx_router_match) ||
       !CU_add_test(pSuite, "router_match_wildcard",
                    shrpx::test_shrpx_router_match_wildcard) ||
@@ -197,6 +199,7 @@ int main(int argc, char *argv[]) {
                    shrpx::test_util_extract_host) ||
       !CU_add_test(pSuite, "util_split_hostport",
                    shrpx::test_util_split_hostport) ||
+      !CU_add_test(pSuite, "util_split_str", shrpx::test_util_split_str) ||
       !CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate) ||
       !CU_add_test(pSuite, "buffer_write", nghttp2::test_buffer_write) ||
       !CU_add_test(pSuite, "pool_recycle", nghttp2::test_pool_recycle) ||
index 4ff5e47..14427f9 100644 (file)
@@ -71,6 +71,7 @@
 
 #include <openssl/ssl.h>
 #include <openssl/err.h>
+#include <openssl/rand.h>
 #include <ev.h>
 
 #include <nghttp2/nghttp2.h>
@@ -86,6 +87,7 @@
 #include "shrpx_signal.h"
 #include "shrpx_connection.h"
 #include "shrpx_log.h"
+#include "shrpx_http.h"
 #include "util.h"
 #include "app_helper.h"
 #include "tls.h"
@@ -124,12 +126,21 @@ constexpr auto ENV_UNIX_PATH = StringRef::from_lit("NGHTTP2_UNIX_PATH");
 // descriptor.  <PATH> is a path to UNIX domain socket.
 constexpr auto ENV_ACCEPT_PREFIX = StringRef::from_lit("NGHTTPX_ACCEPT_");
 
-// This environment variable contains PID of the original master
-// process, assuming that it created this master process as a result
-// of SIGUSR2.  The new master process is expected to send QUIT signal
-// to the original master process to shut it down gracefully.
+// This environment variable contains PID of the original main
+// process, assuming that it created this main process as a result of
+// SIGUSR2.  The new main process is expected to send QUIT signal to
+// the original main process to shut it down gracefully.
 constexpr auto ENV_ORIG_PID = StringRef::from_lit("NGHTTPX_ORIG_PID");
 
+// Prefix of environment variables to tell new binary the QUIC IPC
+// file descriptor and CID prefix of the lingering worker process.
+// The value must be comma separated parameters:
+// <FD>,<CID_PREFIX_0>,<CID_PREFIX_1>,...  <FD> is the file
+// descriptor.  <CID_PREFIX_I> is the I-th CID prefix in hex encoded
+// string.
+constexpr auto ENV_QUIC_WORKER_PROCESS_PREFIX =
+    StringRef::from_lit("NGHTTPX_QUIC_WORKER_PROCESS_");
+
 #ifndef _KERNEL_FASTOPEN
 #  define _KERNEL_FASTOPEN
 // conditional define for TCP_FASTOPEN mostly on ubuntu
@@ -181,8 +192,24 @@ void worker_process_child_cb(struct ev_loop *loop, ev_child *w, int revents);
 } // namespace
 
 struct WorkerProcess {
-  WorkerProcess(struct ev_loop *loop, pid_t worker_pid, int ipc_fd)
-      : loop(loop), worker_pid(worker_pid), ipc_fd(ipc_fd) {
+  WorkerProcess(struct ev_loop *loop, pid_t worker_pid, int ipc_fd
+#ifdef ENABLE_HTTP3
+                ,
+                int quic_ipc_fd,
+                const std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>>
+                    &cid_prefixes
+#endif // ENABLE_HTTP3
+                )
+      : loop(loop),
+        worker_pid(worker_pid),
+        ipc_fd(ipc_fd),
+        termination_deadline(0.)
+#ifdef ENABLE_HTTP3
+        ,
+        quic_ipc_fd(quic_ipc_fd),
+        cid_prefixes(cid_prefixes)
+#endif // ENABLE_HTTP3
+  {
     ev_signal_init(&reopen_log_signalev, signal_cb, REOPEN_LOG_SIGNAL);
     reopen_log_signalev.data = this;
     ev_signal_start(loop, &reopen_log_signalev);
@@ -211,6 +238,12 @@ struct WorkerProcess {
 
     ev_child_stop(loop, &worker_process_childev);
 
+#ifdef ENABLE_HTTP3
+    if (quic_ipc_fd != -1) {
+      close(quic_ipc_fd);
+    }
+#endif // ENABLE_HTTP3
+
     if (ipc_fd != -1) {
       shutdown(ipc_fd, SHUT_WR);
       close(ipc_fd);
@@ -232,6 +265,11 @@ struct WorkerProcess {
   struct ev_loop *loop;
   pid_t worker_pid;
   int ipc_fd;
+  ev_tstamp termination_deadline;
+#ifdef ENABLE_HTTP3
+  int quic_ipc_fd;
+  std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes;
+#endif // ENABLE_HTTP3
 };
 
 namespace {
@@ -243,13 +281,81 @@ std::deque<std::unique_ptr<WorkerProcess>> worker_processes;
 } // namespace
 
 namespace {
+ev_timer worker_process_grace_period_timer;
+} // namespace
+
+namespace {
+void worker_process_grace_period_timercb(struct ev_loop *loop, ev_timer *w,
+                                         int revents) {
+  auto now = ev_now(loop);
+  ev_tstamp next_repeat = 0.;
+
+  for (auto it = std::begin(worker_processes);
+       it != std::end(worker_processes);) {
+    auto &wp = *it;
+    if (!(wp->termination_deadline > 0.)) {
+      ++it;
+
+      continue;
+    }
+
+    auto d = wp->termination_deadline - now;
+    if (d > 0) {
+      if (!(next_repeat > 0.) || d < next_repeat) {
+        next_repeat = d;
+      }
+
+      ++it;
+
+      continue;
+    }
+
+    LOG(NOTICE) << "Deleting worker process pid=" << wp->worker_pid
+                << " because its grace shutdown period is over";
+
+    it = worker_processes.erase(it);
+  }
+
+  if (next_repeat > 0.) {
+    w->repeat = next_repeat;
+    ev_timer_again(loop, w);
+
+    return;
+  }
+
+  ev_timer_stop(loop, w);
+}
+} // namespace
+
+namespace {
+void worker_process_set_termination_deadline(WorkerProcess *wp,
+                                             struct ev_loop *loop) {
+  auto config = get_config();
+
+  if (!(config->worker_process_grace_shutdown_period > 0.)) {
+    return;
+  }
+
+  wp->termination_deadline =
+      ev_now(loop) + config->worker_process_grace_shutdown_period;
+
+  if (!ev_is_active(&worker_process_grace_period_timer)) {
+    worker_process_grace_period_timer.repeat =
+        config->worker_process_grace_shutdown_period;
+
+    ev_timer_again(loop, &worker_process_grace_period_timer);
+  }
+}
+} // namespace
+
+namespace {
 void worker_process_add(std::unique_ptr<WorkerProcess> wp) {
   worker_processes.push_back(std::move(wp));
 }
 } // namespace
 
 namespace {
-void worker_process_remove(const WorkerProcess *wp) {
+void worker_process_remove(const WorkerProcess *wp, struct ev_loop *loop) {
   for (auto it = std::begin(worker_processes); it != std::end(worker_processes);
        ++it) {
     auto &s = *it;
@@ -259,28 +365,46 @@ void worker_process_remove(const WorkerProcess *wp) {
     }
 
     worker_processes.erase(it);
+
+    if (worker_processes.empty()) {
+      ev_timer_stop(loop, &worker_process_grace_period_timer);
+    }
+
     break;
   }
 }
 } // namespace
 
 namespace {
-void worker_process_remove_all() {
+void worker_process_adjust_limit() {
+  auto config = get_config();
+
+  if (config->max_worker_processes &&
+      worker_processes.size() > config->max_worker_processes) {
+    worker_processes.pop_front();
+  }
+}
+} // namespace
+
+namespace {
+void worker_process_remove_all(struct ev_loop *loop) {
   std::deque<std::unique_ptr<WorkerProcess>>().swap(worker_processes);
+
+  ev_timer_stop(loop, &worker_process_grace_period_timer);
 }
 } // namespace
 
 namespace {
 // Send signal |signum| to all worker processes, and clears
 // worker_processes.
-void worker_process_kill(int signum) {
+void worker_process_kill(int signum, struct ev_loop *loop) {
   for (auto &s : worker_processes) {
     if (s->worker_pid == -1) {
       continue;
     }
     kill(s->worker_pid, signum);
   }
-  worker_process_remove_all();
+  worker_process_remove_all(loop);
 }
 } // namespace
 
@@ -419,7 +543,7 @@ void exec_binary() {
 
   // child process
 
-  shrpx_signal_unset_master_proc_ign_handler();
+  shrpx_signal_unset_main_proc_ign_handler();
 
   rv = shrpx_signal_unblock_all();
   if (rv != 0) {
@@ -454,8 +578,8 @@ void exec_binary() {
   auto &listenerconf = config->conn.listener;
 
   // 2 for ENV_ORIG_PID and terminal nullptr.
-  auto envp =
-      std::make_unique<char *[]>(envlen + listenerconf.addrs.size() + 2);
+  auto envp = std::make_unique<char *[]>(envlen + listenerconf.addrs.size() +
+                                         worker_processes.size() + 2);
   size_t envidx = 0;
 
   std::vector<ImmutableString> fd_envs;
@@ -483,6 +607,24 @@ void exec_binary() {
   ipc_fd_str += util::utos(config->pid);
   envp[envidx++] = const_cast<char *>(ipc_fd_str.c_str());
 
+#ifdef ENABLE_HTTP3
+  std::vector<ImmutableString> quic_lwps;
+  for (size_t i = 0; i < worker_processes.size(); ++i) {
+    auto &wp = worker_processes[i];
+    auto s = ENV_QUIC_WORKER_PROCESS_PREFIX.str();
+    s += util::utos(i + 1);
+    s += '=';
+    s += util::utos(wp->quic_ipc_fd);
+    for (auto &cid_prefix : wp->cid_prefixes) {
+      s += ',';
+      s += util::format_hex(cid_prefix);
+    }
+
+    quic_lwps.emplace_back(s);
+    envp[envidx++] = const_cast<char *>(quic_lwps.back().c_str());
+  }
+#endif // ENABLE_HTTP3
+
   for (size_t i = 0; i < envlen; ++i) {
     auto env = StringRef{environ[i]};
     if (util::starts_with(env, ENV_ACCEPT_PREFIX) ||
@@ -491,7 +633,8 @@ void exec_binary() {
         util::starts_with(env, ENV_PORT) ||
         util::starts_with(env, ENV_UNIX_FD) ||
         util::starts_with(env, ENV_UNIX_PATH) ||
-        util::starts_with(env, ENV_ORIG_PID)) {
+        util::starts_with(env, ENV_ORIG_PID) ||
+        util::starts_with(env, ENV_QUIC_WORKER_PROCESS_PREFIX)) {
       continue;
     }
 
@@ -548,7 +691,7 @@ void ipc_send(WorkerProcess *wp, uint8_t ipc_event) {
 
 namespace {
 void reopen_log(WorkerProcess *wp) {
-  LOG(NOTICE) << "Reopening log files: master process";
+  LOG(NOTICE) << "Reopening log files: main process";
 
   auto config = get_config();
   auto &loggingconf = config->logging;
@@ -580,13 +723,14 @@ void signal_cb(struct ev_loop *loop, ev_signal *w, int revents) {
       close(addr.fd);
     }
     ipc_send(wp, SHRPX_IPC_GRACEFUL_SHUTDOWN);
+    worker_process_set_termination_deadline(wp, loop);
     return;
   }
   case RELOAD_SIGNAL:
     reload_config(wp);
     return;
   default:
-    worker_process_kill(w->signum);
+    worker_process_kill(w->signum, loop);
     ev_break(loop);
     return;
   }
@@ -601,7 +745,7 @@ void worker_process_child_cb(struct ev_loop *loop, ev_child *w, int revents) {
 
   auto pid = wp->worker_pid;
 
-  worker_process_remove(wp);
+  worker_process_remove(wp, loop);
 
   if (worker_process_last_pid() == pid) {
     ev_break(loop);
@@ -1092,7 +1236,7 @@ void close_unused_inherited_addr(const std::vector<InheritedAddr> &iaddrs) {
 } // namespace
 
 namespace {
-// Returns the PID of the original master process from environment
+// Returns the PID of the original main process from environment
 // variable ENV_ORIG_PID.
 pid_t get_orig_pid_from_env() {
   auto s = getenv(ENV_ORIG_PID.c_str());
@@ -1103,6 +1247,86 @@ pid_t get_orig_pid_from_env() {
 }
 } // namespace
 
+#ifdef ENABLE_HTTP3
+namespace {
+std::vector<QUICLingeringWorkerProcess>
+    inherited_quic_lingering_worker_processes;
+} // namespace
+
+namespace {
+std::vector<QUICLingeringWorkerProcess>
+get_inherited_quic_lingering_worker_process_from_env() {
+  std::vector<QUICLingeringWorkerProcess> iwps;
+
+  for (size_t i = 1;; ++i) {
+    auto name = ENV_QUIC_WORKER_PROCESS_PREFIX.str();
+    name += util::utos(i);
+    auto env = getenv(name.c_str());
+    if (!env) {
+      break;
+    }
+
+    if (LOG_ENABLED(INFO)) {
+      LOG(INFO) << "Read env " << name << "=" << env;
+    }
+
+    auto envend = env + strlen(env);
+
+    auto end_fd = std::find(env, envend, ',');
+    if (end_fd == envend) {
+      continue;
+    }
+
+    auto fd =
+        util::parse_uint(reinterpret_cast<const uint8_t *>(env), end_fd - env);
+    if (fd == -1) {
+      LOG(WARN) << "Could not parse file descriptor from "
+                << StringRef{env, static_cast<size_t>(end_fd - env)};
+      continue;
+    }
+
+    if (LOG_ENABLED(INFO)) {
+      LOG(INFO) << "Inherit worker process QUIC IPC socket fd=" << fd;
+    }
+
+    util::make_socket_closeonexec(fd);
+
+    std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes;
+
+    auto p = end_fd + 1;
+    for (;;) {
+      auto end = std::find(p, envend, ',');
+
+      auto hex_cid_prefix = StringRef{p, end};
+      if (hex_cid_prefix.size() != SHRPX_QUIC_CID_PREFIXLEN * 2 ||
+          !util::is_hex_string(hex_cid_prefix)) {
+        LOG(WARN) << "Found invalid CID prefix=" << hex_cid_prefix;
+        break;
+      }
+
+      if (LOG_ENABLED(INFO)) {
+        LOG(INFO) << "Inherit worker process CID prefix=" << hex_cid_prefix;
+      }
+
+      cid_prefixes.emplace_back();
+
+      util::decode_hex(std::begin(cid_prefixes.back()), hex_cid_prefix);
+
+      if (end == envend) {
+        break;
+      }
+
+      p = end + 1;
+    }
+
+    iwps.emplace_back(std::move(cid_prefixes), fd);
+  }
+
+  return iwps;
+}
+} // namespace
+#endif // ENABLE_HTTP3
+
 namespace {
 int create_acceptor_socket(Config *config, std::vector<InheritedAddr> &iaddrs) {
   std::array<char, STRERROR_BUFSIZE> errbuf;
@@ -1180,14 +1404,98 @@ int create_ipc_socket(std::array<int, 2> &ipc_fd) {
 }
 } // namespace
 
+#ifdef ENABLE_HTTP3
+namespace {
+int create_quic_ipc_socket(std::array<int, 2> &quic_ipc_fd) {
+  std::array<char, STRERROR_BUFSIZE> errbuf;
+  int rv;
+
+  rv = socketpair(AF_UNIX, SOCK_DGRAM, 0, quic_ipc_fd.data());
+  if (rv == -1) {
+    auto error = errno;
+    LOG(WARN) << "Failed to create socket pair to communicate worker process: "
+              << xsi_strerror(error, errbuf.data(), errbuf.size());
+    return -1;
+  }
+
+  for (auto fd : quic_ipc_fd) {
+    util::make_socket_nonblocking(fd);
+  }
+
+  return 0;
+}
+} // namespace
+
+namespace {
+int generate_cid_prefix(
+    std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> &cid_prefixes,
+    const Config *config) {
+  auto &apiconf = config->api;
+  auto &quicconf = config->quic;
+
+  size_t num_cid_prefix;
+  if (config->single_thread) {
+    num_cid_prefix = 1;
+  } else {
+    num_cid_prefix = config->num_worker;
+
+    // API endpoint occupies the one dedicated worker thread.
+    // Although such worker never gets QUIC traffic, we create CID
+    // prefix for it to make code a bit simpler.
+    if (apiconf.enabled) {
+      ++num_cid_prefix;
+    }
+  }
+
+  cid_prefixes.resize(num_cid_prefix);
+
+  for (auto &cid_prefix : cid_prefixes) {
+    if (create_cid_prefix(cid_prefix.data(), quicconf.server_id.data()) != 0) {
+      return -1;
+    }
+  }
+
+  return 0;
+}
+} // namespace
+
+namespace {
+std::vector<QUICLingeringWorkerProcess>
+collect_quic_lingering_worker_processes() {
+  std::vector<QUICLingeringWorkerProcess> quic_lwps{
+      std::begin(inherited_quic_lingering_worker_processes),
+      std::end(inherited_quic_lingering_worker_processes)};
+
+  for (auto &wp : worker_processes) {
+    quic_lwps.emplace_back(wp->cid_prefixes, wp->quic_ipc_fd);
+  }
+
+  return quic_lwps;
+}
+} // namespace
+#endif // ENABLE_HTTP3
+
 namespace {
 // Creates worker process, and returns PID of worker process.  On
 // success, file descriptor for IPC (send only) is assigned to
 // |main_ipc_fd|.  In child process, we will close file descriptors
 // which are inherited from previous configuration/process, but not
 // used in the current configuration.
-pid_t fork_worker_process(int &main_ipc_fd,
-                          const std::vector<InheritedAddr> &iaddrs) {
+pid_t fork_worker_process(
+    int &main_ipc_fd
+#ifdef ENABLE_HTTP3
+    ,
+    int &wp_quic_ipc_fd
+#endif // ENABLE_HTTP3
+    ,
+    const std::vector<InheritedAddr> &iaddrs
+#ifdef ENABLE_HTTP3
+    ,
+    const std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>>
+        &cid_prefixes,
+    const std::vector<QUICLingeringWorkerProcess> &quic_lwps
+#endif // ENABLE_HTTP3
+) {
   std::array<char, STRERROR_BUFSIZE> errbuf;
   int rv;
   sigset_t oldset;
@@ -1199,6 +1507,15 @@ pid_t fork_worker_process(int &main_ipc_fd,
     return -1;
   }
 
+#ifdef ENABLE_HTTP3
+  std::array<int, 2> quic_ipc_fd;
+
+  rv = create_quic_ipc_socket(quic_ipc_fd);
+  if (rv != 0) {
+    return -1;
+  }
+#endif // ENABLE_HTTP3
+
   rv = shrpx_signal_block_all(&oldset);
   if (rv != 0) {
     auto error = errno;
@@ -1226,9 +1543,23 @@ pid_t fork_worker_process(int &main_ipc_fd,
       util::make_socket_closeonexec(addr.fd);
     }
 
+#ifdef ENABLE_HTTP3
+    util::make_socket_closeonexec(quic_ipc_fd[0]);
+
+    for (auto &lwp : quic_lwps) {
+      util::make_socket_closeonexec(lwp.quic_ipc_fd);
+    }
+
+    for (auto &wp : worker_processes) {
+      util::make_socket_closeonexec(wp->quic_ipc_fd);
+      // Do not close quic_ipc_fd.
+      wp->quic_ipc_fd = -1;
+    }
+#endif // ENABLE_HTTP3
+
     // Remove all WorkerProcesses to stop any registered watcher on
     // default loop.
-    worker_process_remove_all();
+    worker_process_remove_all(EV_DEFAULT);
 
     close_unused_inherited_addr(iaddrs);
 
@@ -1249,9 +1580,19 @@ pid_t fork_worker_process(int &main_ipc_fd,
 
     if (!config->single_process) {
       close(ipc_fd[1]);
+#ifdef ENABLE_HTTP3
+      close(quic_ipc_fd[1]);
+#endif // ENABLE_HTTP3
     }
 
-    WorkerProcessConfig wpconf{ipc_fd[0]};
+    WorkerProcessConfig wpconf{
+        .ipc_fd = ipc_fd[0],
+#ifdef ENABLE_HTTP3
+        .cid_prefixes = cid_prefixes,
+        .quic_ipc_fd = quic_ipc_fd[0],
+        .quic_lingering_worker_processes = quic_lwps,
+#endif // ENABLE_HTTP3
+    };
     rv = worker_process_event_loop(&wpconf);
     if (rv != 0) {
       LOG(FATAL) << "Worker process returned error";
@@ -1292,13 +1633,23 @@ pid_t fork_worker_process(int &main_ipc_fd,
   if (pid == -1) {
     close(ipc_fd[0]);
     close(ipc_fd[1]);
+#ifdef ENABLE_HTTP3
+    close(quic_ipc_fd[0]);
+    close(quic_ipc_fd[1]);
+#endif // ENABLE_HTTP3
 
     return -1;
   }
 
   close(ipc_fd[0]);
+#ifdef ENABLE_HTTP3
+  close(quic_ipc_fd[0]);
+#endif // ENABLE_HTTP3
 
   main_ipc_fd = ipc_fd[1];
+#ifdef ENABLE_HTTP3
+  wp_quic_ipc_fd = quic_ipc_fd[1];
+#endif // ENABLE_HTTP3
 
   LOG(NOTICE) << "Worker process [" << pid << "] spawned";
 
@@ -1310,7 +1661,7 @@ namespace {
 int event_loop() {
   std::array<char, STRERROR_BUFSIZE> errbuf;
 
-  shrpx_signal_set_master_proc_ign_handler();
+  shrpx_signal_set_main_proc_ign_handler();
 
   auto config = mod_config();
 
@@ -1345,17 +1696,53 @@ int event_loop() {
 
   auto orig_pid = get_orig_pid_from_env();
 
+#ifdef ENABLE_HTTP3
+  inherited_quic_lingering_worker_processes =
+      get_inherited_quic_lingering_worker_process_from_env();
+#endif // ENABLE_HTTP3
+
   auto loop = ev_default_loop(config->ev_loop_flags);
 
   int ipc_fd = 0;
+#ifdef ENABLE_HTTP3
+  int quic_ipc_fd = 0;
+
+  auto quic_lwps = collect_quic_lingering_worker_processes();
 
-  auto pid = fork_worker_process(ipc_fd, {});
+  std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes;
+
+  if (generate_cid_prefix(cid_prefixes, config) != 0) {
+    return -1;
+  }
+#endif // ENABLE_HTTP3
+
+  auto pid = fork_worker_process(
+      ipc_fd
+#ifdef ENABLE_HTTP3
+      ,
+      quic_ipc_fd
+#endif // ENABLE_HTTP3
+      ,
+      {}
+#ifdef ENABLE_HTTP3
+      ,
+      cid_prefixes, quic_lwps
+#endif // ENABLE_HTTP3
+  );
 
   if (pid == -1) {
     return -1;
   }
 
-  worker_process_add(std::make_unique<WorkerProcess>(loop, pid, ipc_fd));
+  ev_timer_init(&worker_process_grace_period_timer,
+                worker_process_grace_period_timercb, 0., 0.);
+
+  worker_process_add(std::make_unique<WorkerProcess>(loop, pid, ipc_fd
+#ifdef ENABLE_HTTP3
+                                                     ,
+                                                     quic_ipc_fd, cid_prefixes
+#endif // ENABLE_HTTP3
+                                                     ));
 
   // Write PID file when we are ready to accept connection from peer.
   // This makes easier to write restart script for nghttpx.  Because
@@ -1369,13 +1756,15 @@ int event_loop() {
   shrpx_sd_notifyf(0, "READY=1");
 
   if (orig_pid != -1) {
-    LOG(NOTICE) << "Send QUIT signal to the original master process to tell "
+    LOG(NOTICE) << "Send QUIT signal to the original main process to tell "
                    "that we are ready to serve requests.";
     kill(orig_pid, SIGQUIT);
   }
 
   ev_run(loop, 0);
 
+  ev_timer_stop(loop, &worker_process_grace_period_timer);
+
   return 0;
 }
 } // namespace
@@ -1548,6 +1937,42 @@ void fill_default_config(Config *config) {
         downstreamconf.option, downstreamconf.encoder_dynamic_table_size);
   }
 
+#ifdef ENABLE_HTTP3
+  auto &quicconf = config->quic;
+  {
+    auto &upstreamconf = quicconf.upstream;
+
+    {
+      auto &timeoutconf = upstreamconf.timeout;
+      timeoutconf.idle = 30_s;
+    }
+
+    auto &bpfconf = quicconf.bpf;
+    bpfconf.prog_file = StringRef::from_lit(PKGLIBDIR "/reuseport_kern.o");
+
+    upstreamconf.congestion_controller = NGTCP2_CC_ALGO_CUBIC;
+
+    upstreamconf.initial_rtt =
+        static_cast<ev_tstamp>(NGTCP2_DEFAULT_INITIAL_RTT) / NGTCP2_SECONDS;
+  }
+
+  if (RAND_bytes(quicconf.server_id.data(), quicconf.server_id.size()) != 1) {
+    assert(0);
+    abort();
+  }
+
+  auto &http3conf = config->http3;
+  {
+    auto &upstreamconf = http3conf.upstream;
+
+    upstreamconf.max_concurrent_streams = 100;
+    upstreamconf.window_size = 256_k;
+    upstreamconf.connection_window_size = 1_m;
+    upstreamconf.max_window_size = 6_m;
+    upstreamconf.max_connection_window_size = 8_m;
+  }
+#endif // ENABLE_HTTP3
+
   auto &loggingconf = config->logging;
   {
     auto &accessconf = loggingconf.access;
@@ -1578,6 +2003,9 @@ void fill_default_config(Config *config) {
       // Read timeout for HTTP2 upstream connection
       timeoutconf.http2_read = 3_min;
 
+      // Read timeout for HTTP3 upstream connection
+      timeoutconf.http3_read = 3_min;
+
       // Read timeout for non-HTTP2 upstream connection
       timeoutconf.read = 1_min;
 
@@ -1632,7 +2060,7 @@ void print_version(std::ostream &out) {
 namespace {
 void print_usage(std::ostream &out) {
   out << R"(Usage: nghttpx [OPTIONS]... [<PRIVATE_KEY> <CERT>]
-A reverse proxy for HTTP/2, and HTTP/1.)"
+A reverse proxy for HTTP/3, HTTP/2, and HTTP/1.)"
       << std::endl;
 }
 } // namespace
@@ -1740,12 +2168,13 @@ Connections:
               "affinity=<METHOD>",    "dns",    "redirect-if-not-tls",
               "upgrade-scheme",                        "mruby=<PATH>",
               "read-timeout=<DURATION>",   "write-timeout=<DURATION>",
-              "group=<GROUP>",  "group-weight=<N>", and  "weight=<N>".
-              The  parameter  consists   of  keyword,  and  optionally
-              followed by  "=" and value.  For  example, the parameter
-              "proto=h2"  consists of  the keyword  "proto" and  value
-              "h2".  The parameter "tls" consists of the keyword "tls"
-              without value.  Each parameter is described as follows.
+              "group=<GROUP>",  "group-weight=<N>", "weight=<N>",  and
+              "dnf".    The  parameter   consists   of  keyword,   and
+              optionally followed by "="  and value.  For example, the
+              parameter "proto=h2" consists of the keyword "proto" and
+              value "h2".  The parameter "tls" consists of the keyword
+              "tls"  without value.   Each parameter  is described  as
+              follows.
 
               The backend application protocol  can be specified using
               optional  "proto"   parameter,  and   in  the   form  of
@@ -1876,9 +2305,19 @@ Connections:
               weight  becomes  1.   "weight"  is  ignored  if  session
               affinity is enabled.
 
+              If "dnf" parameter is  specified, an incoming request is
+              not forwarded to a backend  and just consumed along with
+              the  request body  (actually a  backend server  never be
+              contacted).  It  is expected  that the HTTP  response is
+              generated by mruby  script (see "mruby=<PATH>" parameter
+              above).  "dnf" is an abbreviation of "do not forward".
+
               Since ";" and ":" are  used as delimiter, <PATTERN> must
-              not  contain these  characters.  Since  ";" has  special
-              meaning in shell, the option value must be quoted.
+              not contain  these characters.  In order  to include ":"
+              in  <PATTERN>,  one  has  to  specify  "%3A"  (which  is
+              percent-encoded  from of  ":") instead.   Since ";"  has
+              special  meaning  in shell,  the  option  value must  be
+              quoted.
 
               Default: )"
       << DEFAULT_DOWNSTREAM_HOST << "," << DEFAULT_DOWNSTREAM_PORT << R"(
@@ -1918,6 +2357,12 @@ Connections:
               connection,  specify  "proxyproto" parameter.   This  is
               disabled by default.
 
+              To  receive   HTTP/3  (QUIC)  traffic,   specify  "quic"
+              parameter.  It  makes nghttpx listen on  UDP port rather
+              than  TCP   port.   UNIX   domain  socket,   "api",  and
+              "healthmon"  parameters  cannot   be  used  with  "quic"
+              parameter.
+
               Default: *,3000
   --backlog=<N>
               Set listen backlog size.
@@ -2026,6 +2471,12 @@ Performance:
               If 0 is given, nghttpx does not set the limit.
               Default: )"
       << config->rlimit_nofile << R"(
+  --rlimit-memlock=<N>
+              Set maximum number of bytes of memory that may be locked
+              into  RAM.  If  0 is  given,  nghttpx does  not set  the
+              limit.
+              Default: )"
+      << config->rlimit_memlock << R"(
   --backend-request-buffer=<SIZE>
               Set buffer size used to store backend request.
               Default: )"
@@ -2050,6 +2501,10 @@ Timeout:
               Specify read timeout for HTTP/2 frontend connection.
               Default: )"
       << util::duration_str(config->conn.upstream.timeout.http2_read) << R"(
+  --frontend-http3-read-timeout=<DURATION>
+              Specify read timeout for HTTP/3 frontend connection.
+              Default: )"
+      << util::duration_str(config->conn.upstream.timeout.http3_read) << R"(
   --frontend-read-timeout=<DURATION>
               Specify read timeout for HTTP/1.1 frontend connection.
               Default: )"
@@ -2385,16 +2840,16 @@ SSL/TLS:
               TLS HTTP/2 backends.
               Default: )"
       << util::duration_str(config->tls.dyn_rec.idle_timeout) << R"(
-  --no-http2-cipher-black-list
-              Allow  black  listed  cipher suite  on  frontend  HTTP/2
+  --no-http2-cipher-block-list
+              Allow  block  listed  cipher suite  on  frontend  HTTP/2
               connection.                                          See
               https://tools.ietf.org/html/rfc7540#appendix-A  for  the
-              complete HTTP/2 cipher suites black list.
-  --client-no-http2-cipher-black-list
-              Allow  black  listed  cipher  suite  on  backend  HTTP/2
+              complete HTTP/2 cipher suites block list.
+  --client-no-http2-cipher-block-list
+              Allow  block  listed  cipher  suite  on  backend  HTTP/2
               connection.                                          See
               https://tools.ietf.org/html/rfc7540#appendix-A  for  the
-              complete HTTP/2 cipher suites black list.
+              complete HTTP/2 cipher suites block list.
   --tls-sct-dir=<DIR>
               Specifies the  directory where  *.sct files  exist.  All
               *.sct   files   in  <DIR>   are   read,   and  sent   as
@@ -2413,9 +2868,9 @@ SSL/TLS:
               are skipped.  The default  enabled cipher list might not
               contain any PSK cipher suite.  In that case, desired PSK
               cipher suites  must be  enabled using  --ciphers option.
-              The  desired PSK  cipher suite  may be  black listed  by
+              The  desired PSK  cipher suite  may be  block listed  by
               HTTP/2.   To  use  those   cipher  suites  with  HTTP/2,
-              consider  to  use  --no-http2-cipher-black-list  option.
+              consider  to  use  --no-http2-cipher-block-list  option.
               But be aware its implications.
   --client-psk-secrets=<PATH>
               Read PSK identity and secrets from <PATH>.  This is used
@@ -2427,17 +2882,18 @@ SSL/TLS:
               The default  enabled cipher  list might not  contain any
               PSK  cipher suite.   In  that case,  desired PSK  cipher
               suites  must be  enabled using  --client-ciphers option.
-              The  desired PSK  cipher suite  may be  black listed  by
+              The  desired PSK  cipher suite  may be  block listed  by
               HTTP/2.   To  use  those   cipher  suites  with  HTTP/2,
-              consider   to  use   --client-no-http2-cipher-black-list
+              consider   to  use   --client-no-http2-cipher-block-list
               option.  But be aware its implications.
   --tls-no-postpone-early-data
-              By default,  nghttpx postpones forwarding  HTTP requests
-              sent in early data, including those sent in partially in
-              it, until TLS handshake finishes.  If all backend server
-              recognizes "Early-Data" header  field, using this option
-              makes nghttpx  not postpone  forwarding request  and get
-              full potential of 0-RTT data.
+              By  default,   except  for  QUIC   connections,  nghttpx
+              postpones forwarding  HTTP requests sent in  early data,
+              including  those  sent in  partially  in  it, until  TLS
+              handshake  finishes.  If  all backend  server recognizes
+              "Early-Data"  header  field,  using  this  option  makes
+              nghttpx  not postpone  forwarding request  and get  full
+              potential of 0-RTT data.
   --tls-max-early-data=<SIZE>
               Sets  the  maximum  amount  of 0-RTT  data  that  server
               accepts.
@@ -2607,6 +3063,14 @@ Logging:
                 request.  "-" if backend host is not available.
               * $backend_port:  backend  port   used  to  fulfill  the
                 request.  "-" if backend host is not available.
+              * $method: HTTP method
+              * $path:  Request  path  including query.   For  CONNECT
+                request, authority is recorded.
+              * $path_without_query:  $path   up  to  the   first  '?'
+                character.    For   CONNECT  request,   authority   is
+                recorded.
+              * $protocol_version:   HTTP  version   (e.g.,  HTTP/1.1,
+                HTTP/2)
 
               The  variable  can  be  enclosed  by  "{"  and  "}"  for
               disambiguation (e.g., ${remote_addr}).
@@ -2693,13 +3157,18 @@ HTTP:
               Rewrite  host and  :authority header  fields in  default
               mode.  When  --http2-proxy is  used, these  headers will
               not be altered regardless of this option.
-  --altsvc=<PROTOID,PORT[,HOST,[ORIGIN]]>
+  --altsvc=<PROTOID,PORT[,HOST,[ORIGIN[,PARAMS]]]>
               Specify   protocol  ID,   port,  host   and  origin   of
-              alternative service.  <HOST>  and <ORIGIN> are optional.
-              They  are advertised  in  alt-svc header  field only  in
-              HTTP/1.1  frontend.  This  option can  be used  multiple
-              times   to   specify  multiple   alternative   services.
-              Example: --altsvc=h2,443
+              alternative service.  <HOST>,  <ORIGIN> and <PARAMS> are
+              optional.   Empty <HOST>  and <ORIGIN>  are allowed  and
+              they  are treated  as  nothing is  specified.  They  are
+              advertised  in alt-svc  header  field  only in  HTTP/1.1
+              frontend.   This option  can be  used multiple  times to
+              specify multiple alternative services.
+              Example: --altsvc="h2,443,,,ma=3600; persist=1'
+  --http2-altsvc=<PROTOID,PORT[,HOST,[ORIGIN[,PARAMS]]]>
+              Just like --altsvc option, but  this altsvc is only sent
+              in HTTP/2 frontend.
   --add-request-header=<HEADER>
               Specify additional header field to add to request header
               set.  This  option just  appends header field  and won't
@@ -2822,11 +3291,32 @@ Process:
   --single-process
               Run this program in a  single process mode for debugging
               purpose.  Without this option,  nghttpx creates at least
-              2  processes:  master  and worker  processes.   If  this
-              option is  used, master  and worker  are unified  into a
-              single process.  nghttpx still spawns additional process
-              if neverbleed is used.  In  the single process mode, the
+              2 processes: main and  worker processes.  If this option
+              is  used, main  and  worker are  unified  into a  single
+              process.   nghttpx still  spawns  additional process  if
+              neverbleed  is used.   In the  single process  mode, the
               signal handling feature is disabled.
+  --max-worker-processes=<N>
+              The maximum number of  worker processes.  nghttpx spawns
+              new worker  process when  it reloads  its configuration.
+              The previous worker  process enters graceful termination
+              period and will terminate  when it finishes handling the
+              existing    connections.     However,    if    reloading
+              configurations  happen   very  frequently,   the  worker
+              processes might be piled up if they take a bit long time
+              to finish  the existing connections.  With  this option,
+              if  the number  of  worker processes  exceeds the  given
+              value,   the  oldest   worker   process  is   terminated
+              immediately.  Specifying 0 means no  limit and it is the
+              default behaviour.
+  --worker-process-grace-shutdown-period=<DURATION>
+              Maximum  period  for  a   worker  process  to  terminate
+              gracefully.  When  a worker  process enters  in graceful
+              shutdown   period  (e.g.,   when  nghttpx   reloads  its
+              configuration)  and  it  does not  finish  handling  the
+              existing connections in the given  period of time, it is
+              immediately terminated.  Specifying 0 means no limit and
+              it is the default behaviour.
 
 Scripting:
   --mruby-file=<PATH>
@@ -2835,7 +3325,124 @@ Scripting:
               Ignore mruby compile error  for per-pattern mruby script
               file.  If error  occurred, it is treated as  if no mruby
               file were specified for the pattern.
+)";
 
+#ifdef ENABLE_HTTP3
+  out << R"(
+HTTP/3 and QUIC:
+  --frontend-quic-idle-timeout=<DURATION>
+              Specify an idle timeout for QUIC connection.
+              Default: )"
+      << util::duration_str(config->quic.upstream.timeout.idle) << R"(
+  --frontend-quic-debug-log
+              Output QUIC debug log to /dev/stderr.
+  --quic-bpf-program-file=<PATH>
+              Specify a path to  eBPF program file reuseport_kern.o to
+              direct  an  incoming  QUIC  UDP datagram  to  a  correct
+              socket.
+              Default: )"
+      << config->quic.bpf.prog_file << R"(
+  --frontend-quic-early-data
+              Enable early data on frontend QUIC connections.  nghttpx
+              sends "Early-Data" header field to a backend server if a
+              request is received in early  data and handshake has not
+              finished.  All backend servers should deal with possibly
+              replayed requests.
+  --frontend-quic-qlog-dir=<DIR>
+              Specify a  directory where  a qlog  file is  written for
+              frontend QUIC  connections.  A qlog file  is created per
+              each QUIC  connection.  The  file name is  ISO8601 basic
+              format, followed by "-", server Source Connection ID and
+              ".qlog".
+  --frontend-quic-require-token
+              Require an address validation  token for a frontend QUIC
+              connection.   Server sends  a token  in Retry  packet or
+              NEW_TOKEN frame in the previous connection.
+  --frontend-quic-congestion-controller=<CC>
+              Specify a congestion controller algorithm for a frontend
+              QUIC  connection.   <CC>  should be  either  "cubic"  or
+              "bbr".
+              Default: )"
+      << (config->quic.upstream.congestion_controller == NGTCP2_CC_ALGO_CUBIC
+              ? "cubic"
+              : "bbr")
+      << R"(
+  --frontend-quic-secret-file=<PATH>
+              Path to file that contains secure random data to be used
+              as QUIC keying materials.  It is used to derive keys for
+              encrypting tokens and Connection IDs.  It is not used to
+              encrypt  QUIC  packets.  Each  line  of  this file  must
+              contain  exactly  136  bytes  hex-encoded  string  (when
+              decoded the byte string is  68 bytes long).  The first 2
+              bits of  decoded byte  string are  used to  identify the
+              keying material.  An  empty line or a  line which starts
+              '#'  is ignored.   The file  can contain  more than  one
+              keying materials.  Because the  identifier is 2 bits, at
+              most 4 keying materials are  read and the remaining data
+              is discarded.  The first keying  material in the file is
+              primarily  used for  encryption and  decryption for  new
+              connection.  The other ones are used to decrypt data for
+              the  existing connections.   Specifying multiple  keying
+              materials enables  key rotation.   Please note  that key
+              rotation  does  not  occur automatically.   User  should
+              update  files  or  change  options  values  and  restart
+              nghttpx gracefully.   If opening  or reading  given file
+              fails, all loaded keying  materials are discarded and it
+              is treated as if none of  this option is given.  If this
+              option is not  given or an error  occurred while opening
+              or  reading  a  file,  a keying  material  is  generated
+              internally on startup and reload.
+  --quic-server-id=<HEXSTRING>
+              Specify server  ID encoded in Connection  ID to identify
+              this  particular  server  instance.   Connection  ID  is
+              encrypted and  this part is  not visible in  public.  It
+              must be 4  bytes long and must be encoded  in hex string
+              (which is 8  bytes long).  If this option  is omitted, a
+              random   server  ID   is   generated   on  startup   and
+              configuration reload.
+  --frontend-quic-initial-rtt=<DURATION>
+              Specify the initial RTT of the frontend QUIC connection.
+              Default: )"
+      << util::duration_str(config->quic.upstream.initial_rtt) << R"(
+  --no-quic-bpf
+              Disable eBPF.
+  --frontend-http3-window-size=<SIZE>
+              Sets  the  per-stream  initial  window  size  of  HTTP/3
+              frontend connection.
+              Default: )"
+      << util::utos_unit(config->http3.upstream.window_size) << R"(
+  --frontend-http3-connection-window-size=<SIZE>
+              Sets the  per-connection window size of  HTTP/3 frontend
+              connection.
+              Default: )"
+      << util::utos_unit(config->http3.upstream.connection_window_size) << R"(
+  --frontend-http3-max-window-size=<SIZE>
+              Sets  the  maximum  per-stream  window  size  of  HTTP/3
+              frontend connection.  The window  size is adjusted based
+              on the receiving rate of stream data.  The initial value
+              is the  value specified  by --frontend-http3-window-size
+              and the window size grows up to <SIZE> bytes.
+              Default: )"
+      << util::utos_unit(config->http3.upstream.max_window_size) << R"(
+  --frontend-http3-max-connection-window-size=<SIZE>
+              Sets the  maximum per-connection  window size  of HTTP/3
+              frontend connection.  The window  size is adjusted based
+              on the receiving rate of stream data.  The initial value
+              is         the         value        specified         by
+              --frontend-http3-connection-window-size  and the  window
+              size grows up to <SIZE> bytes.
+              Default: )"
+      << util::utos_unit(config->http3.upstream.max_connection_window_size)
+      << R"(
+  --frontend-http3-max-concurrent-streams=<N>
+              Set the maximum number of  the concurrent streams in one
+              frontend HTTP/3 connection.
+              Default: )"
+      << config->http3.upstream.max_concurrent_streams << R"(
+)";
+#endif // ENABLE_HTTP3
+
+  out << R"(
 Misc:
   --conf=<PATH>
               Load  configuration  from   <PATH>.   Please  note  that
@@ -3016,8 +3623,10 @@ int process_options(Config *config,
     addr.port = 3000;
     addr.tls = true;
     addr.family = AF_INET;
+    addr.index = 0;
     listenerconf.addrs.push_back(addr);
     addr.family = AF_INET6;
+    addr.index = 1;
     listenerconf.addrs.push_back(std::move(addr));
   }
 
@@ -3048,9 +3657,12 @@ int process_options(Config *config,
     return -1;
   }
 
+  std::array<char, util::max_hostport> hostport_buf;
+
   auto &proxy = config->downstream_http_proxy;
   if (!proxy.host.empty()) {
-    auto hostport = util::make_hostport(StringRef{proxy.host}, proxy.port);
+    auto hostport = util::make_hostport(std::begin(hostport_buf),
+                                        StringRef{proxy.host}, proxy.port);
     if (resolve_hostname(&proxy.addr, proxy.host.c_str(), proxy.port,
                          AF_UNSPEC) == -1) {
       LOG(FATAL) << "Resolving backend HTTP proxy address failed: " << hostport;
@@ -3063,7 +3675,8 @@ int process_options(Config *config,
   {
     auto &memcachedconf = tlsconf.session_cache.memcached;
     if (!memcachedconf.host.empty()) {
-      auto hostport = util::make_hostport(StringRef{memcachedconf.host},
+      auto hostport = util::make_hostport(std::begin(hostport_buf),
+                                          StringRef{memcachedconf.host},
                                           memcachedconf.port);
       if (resolve_hostname(&memcachedconf.addr, memcachedconf.host.c_str(),
                            memcachedconf.port, memcachedconf.family) == -1) {
@@ -3084,7 +3697,8 @@ int process_options(Config *config,
   {
     auto &memcachedconf = tlsconf.ticket.memcached;
     if (!memcachedconf.host.empty()) {
-      auto hostport = util::make_hostport(StringRef{memcachedconf.host},
+      auto hostport = util::make_hostport(std::begin(hostport_buf),
+                                          StringRef{memcachedconf.host},
                                           memcachedconf.port);
       if (resolve_hostname(&memcachedconf.addr, memcachedconf.host.c_str(),
                            memcachedconf.port, memcachedconf.family) == -1) {
@@ -3111,6 +3725,16 @@ int process_options(Config *config,
     }
   }
 
+  if (config->rlimit_memlock) {
+    struct rlimit lim = {static_cast<rlim_t>(config->rlimit_memlock),
+                         static_cast<rlim_t>(config->rlimit_memlock)};
+    if (setrlimit(RLIMIT_MEMLOCK, &lim) != 0) {
+      auto error = errno;
+      LOG(WARN) << "Setting rlimit-memlock failed: "
+                << xsi_strerror(error, errbuf.data(), errbuf.size());
+    }
+  }
+
   auto &fwdconf = config->http.forwarded;
 
   if (fwdconf.by_node_type == ForwardedNode::OBFUSCATED &&
@@ -3137,6 +3761,16 @@ int process_options(Config *config,
   config->http2.upstream.callbacks = create_http2_upstream_callbacks();
   config->http2.downstream.callbacks = create_http2_downstream_callbacks();
 
+  if (!config->http.altsvcs.empty()) {
+    config->http.altsvc_header_value =
+        http::create_altsvc_header_value(config->balloc, config->http.altsvcs);
+  }
+
+  if (!config->http.http2_altsvcs.empty()) {
+    config->http.http2_altsvc_header_value = http::create_altsvc_header_value(
+        config->balloc, config->http.http2_altsvcs);
+  }
+
   return 0;
 }
 } // namespace
@@ -3199,13 +3833,37 @@ void reload_config(WorkerProcess *wp) {
   auto loop = ev_default_loop(new_config->ev_loop_flags);
 
   int ipc_fd = 0;
+#ifdef ENABLE_HTTP3
+  int quic_ipc_fd = 0;
+
+  auto quic_lwps = collect_quic_lingering_worker_processes();
+
+  std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes;
+
+  if (generate_cid_prefix(cid_prefixes, new_config.get()) != 0) {
+    close_not_inherited_fd(new_config.get(), iaddrs);
+    return;
+  }
+#endif // ENABLE_HTTP3
 
   // fork_worker_process and forked child process assumes new
   // configuration can be obtained from get_config().
 
   auto old_config = replace_config(std::move(new_config));
 
-  auto pid = fork_worker_process(ipc_fd, iaddrs);
+  auto pid = fork_worker_process(ipc_fd
+#ifdef ENABLE_HTTP3
+                                 ,
+                                 quic_ipc_fd
+#endif // ENABLE_HTTP3
+
+                                 ,
+                                 iaddrs
+#ifdef ENABLE_HTTP3
+                                 ,
+                                 cid_prefixes, quic_lwps
+#endif // ENABLE_HTTP3
+  );
 
   if (pid == -1) {
     LOG(ERROR) << "Failed to process new configuration";
@@ -3221,10 +3879,18 @@ void reload_config(WorkerProcess *wp) {
   // Send last worker process a graceful shutdown notice
   auto &last_wp = worker_processes.back();
   ipc_send(last_wp.get(), SHRPX_IPC_GRACEFUL_SHUTDOWN);
+  worker_process_set_termination_deadline(last_wp.get(), loop);
   // We no longer use signals for this worker.
   last_wp->shutdown_signal_watchers();
 
-  worker_process_add(std::make_unique<WorkerProcess>(loop, pid, ipc_fd));
+  worker_process_add(std::make_unique<WorkerProcess>(loop, pid, ipc_fd
+#ifdef ENABLE_HTTP3
+                                                     ,
+                                                     quic_ipc_fd, cid_prefixes
+#endif // ENABLE_HTTP3
+                                                     ));
+
+  worker_process_adjust_limit();
 
   if (!get_config()->pid_file.empty()) {
     save_pid();
@@ -3520,6 +4186,44 @@ int main(int argc, char **argv) {
         {SHRPX_OPT_TLS13_CLIENT_CIPHERS.c_str(), required_argument, &flag, 165},
         {SHRPX_OPT_NO_STRIP_INCOMING_EARLY_DATA.c_str(), no_argument, &flag,
          166},
+        {SHRPX_OPT_NO_HTTP2_CIPHER_BLOCK_LIST.c_str(), no_argument, &flag, 167},
+        {SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST.c_str(), no_argument,
+         &flag, 168},
+        {SHRPX_OPT_QUIC_BPF_PROGRAM_FILE.c_str(), required_argument, &flag,
+         169},
+        {SHRPX_OPT_NO_QUIC_BPF.c_str(), no_argument, &flag, 170},
+        {SHRPX_OPT_HTTP2_ALTSVC.c_str(), required_argument, &flag, 171},
+        {SHRPX_OPT_FRONTEND_HTTP3_READ_TIMEOUT.c_str(), required_argument,
+         &flag, 172},
+        {SHRPX_OPT_FRONTEND_QUIC_IDLE_TIMEOUT.c_str(), required_argument, &flag,
+         173},
+        {SHRPX_OPT_FRONTEND_QUIC_DEBUG_LOG.c_str(), no_argument, &flag, 174},
+        {SHRPX_OPT_FRONTEND_HTTP3_WINDOW_SIZE.c_str(), required_argument, &flag,
+         175},
+        {SHRPX_OPT_FRONTEND_HTTP3_CONNECTION_WINDOW_SIZE.c_str(),
+         required_argument, &flag, 176},
+        {SHRPX_OPT_FRONTEND_HTTP3_MAX_WINDOW_SIZE.c_str(), required_argument,
+         &flag, 177},
+        {SHRPX_OPT_FRONTEND_HTTP3_MAX_CONNECTION_WINDOW_SIZE.c_str(),
+         required_argument, &flag, 178},
+        {SHRPX_OPT_FRONTEND_HTTP3_MAX_CONCURRENT_STREAMS.c_str(),
+         required_argument, &flag, 179},
+        {SHRPX_OPT_FRONTEND_QUIC_EARLY_DATA.c_str(), no_argument, &flag, 180},
+        {SHRPX_OPT_FRONTEND_QUIC_QLOG_DIR.c_str(), required_argument, &flag,
+         181},
+        {SHRPX_OPT_FRONTEND_QUIC_REQUIRE_TOKEN.c_str(), no_argument, &flag,
+         182},
+        {SHRPX_OPT_FRONTEND_QUIC_CONGESTION_CONTROLLER.c_str(),
+         required_argument, &flag, 183},
+        {SHRPX_OPT_QUIC_SERVER_ID.c_str(), required_argument, &flag, 185},
+        {SHRPX_OPT_FRONTEND_QUIC_SECRET_FILE.c_str(), required_argument, &flag,
+         186},
+        {SHRPX_OPT_RLIMIT_MEMLOCK.c_str(), required_argument, &flag, 187},
+        {SHRPX_OPT_MAX_WORKER_PROCESSES.c_str(), required_argument, &flag, 188},
+        {SHRPX_OPT_WORKER_PROCESS_GRACE_SHUTDOWN_PERIOD.c_str(),
+         required_argument, &flag, 189},
+        {SHRPX_OPT_FRONTEND_QUIC_INITIAL_RTT.c_str(), required_argument, &flag,
+         190},
         {nullptr, 0, nullptr, 0}};
 
     int option_index = 0;
@@ -4313,6 +5017,117 @@ int main(int argc, char **argv) {
         cmdcfgs.emplace_back(SHRPX_OPT_NO_STRIP_INCOMING_EARLY_DATA,
                              StringRef::from_lit("yes"));
         break;
+      case 167:
+        // --no-http2-cipher-block-list
+        cmdcfgs.emplace_back(SHRPX_OPT_NO_HTTP2_CIPHER_BLOCK_LIST,
+                             StringRef::from_lit("yes"));
+        break;
+      case 168:
+        // --client-no-http2-cipher-block-list
+        cmdcfgs.emplace_back(SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST,
+                             StringRef::from_lit("yes"));
+        break;
+      case 169:
+        // --quic-bpf-program-file
+        cmdcfgs.emplace_back(SHRPX_OPT_QUIC_BPF_PROGRAM_FILE,
+                             StringRef{optarg});
+        break;
+      case 170:
+        // --no-quic-bpf
+        cmdcfgs.emplace_back(SHRPX_OPT_NO_QUIC_BPF, StringRef::from_lit("yes"));
+        break;
+      case 171:
+        // --http2-altsvc
+        cmdcfgs.emplace_back(SHRPX_OPT_HTTP2_ALTSVC, StringRef{optarg});
+        break;
+      case 172:
+        // --frontend-http3-read-timeout
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_HTTP3_READ_TIMEOUT,
+                             StringRef{optarg});
+        break;
+      case 173:
+        // --frontend-quic-idle-timeout
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_QUIC_IDLE_TIMEOUT,
+                             StringRef{optarg});
+        break;
+      case 174:
+        // --frontend-quic-debug-log
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_QUIC_DEBUG_LOG,
+                             StringRef::from_lit("yes"));
+        break;
+      case 175:
+        // --frontend-http3-window-size
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_HTTP3_WINDOW_SIZE,
+                             StringRef{optarg});
+        break;
+      case 176:
+        // --frontend-http3-connection-window-size
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_HTTP3_CONNECTION_WINDOW_SIZE,
+                             StringRef{optarg});
+        break;
+      case 177:
+        // --frontend-http3-max-window-size
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_HTTP3_MAX_WINDOW_SIZE,
+                             StringRef{optarg});
+        break;
+      case 178:
+        // --frontend-http3-max-connection-window-size
+        cmdcfgs.emplace_back(
+            SHRPX_OPT_FRONTEND_HTTP3_MAX_CONNECTION_WINDOW_SIZE,
+            StringRef{optarg});
+        break;
+      case 179:
+        // --frontend-http3-max-concurrent-streams
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_HTTP3_MAX_CONCURRENT_STREAMS,
+                             StringRef{optarg});
+        break;
+      case 180:
+        // --frontend-quic-early-data
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_QUIC_EARLY_DATA,
+                             StringRef::from_lit("yes"));
+        break;
+      case 181:
+        // --frontend-quic-qlog-dir
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_QUIC_QLOG_DIR,
+                             StringRef{optarg});
+        break;
+      case 182:
+        // --frontend-quic-require-token
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_QUIC_REQUIRE_TOKEN,
+                             StringRef::from_lit("yes"));
+        break;
+      case 183:
+        // --frontend-quic-congestion-controller
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_QUIC_CONGESTION_CONTROLLER,
+                             StringRef{optarg});
+        break;
+      case 185:
+        // --quic-server-id
+        cmdcfgs.emplace_back(SHRPX_OPT_QUIC_SERVER_ID, StringRef{optarg});
+        break;
+      case 186:
+        // --frontend-quic-secret-file
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_QUIC_SECRET_FILE,
+                             StringRef{optarg});
+        break;
+      case 187:
+        // --rlimit-memlock
+        cmdcfgs.emplace_back(SHRPX_OPT_RLIMIT_MEMLOCK, StringRef{optarg});
+        break;
+      case 188:
+        // --max-worker-processes
+        cmdcfgs.emplace_back(SHRPX_OPT_MAX_WORKER_PROCESSES, StringRef{optarg});
+        break;
+      case 189:
+        // --worker-process-grace-shutdown-period
+        cmdcfgs.emplace_back(SHRPX_OPT_WORKER_PROCESS_GRACE_SHUTDOWN_PERIOD,
+                             StringRef{optarg});
+        break;
+      case 190:
+        // --frontend-quic-initial-rtt
+        cmdcfgs.emplace_back(SHRPX_OPT_FRONTEND_QUIC_INITIAL_RTT,
+                             StringRef{optarg});
+        break;
       default:
         break;
       }
index 60e873d..d881ef5 100644 (file)
 inline int initgroups(const char *user, gid_t group) { return 0; }
 #endif // defined(HAVE_DECL_INITGROUPS) && !HAVE_DECL_INITGROUPS
 
+#ifndef HAVE_BPF_STATS_TYPE
+/* Newer kernel should have this defined in linux/bpf.h */
+enum bpf_stats_type {
+  BPF_STATS_RUN_TIME = 0,
+};
+#endif // !HAVE_BPF_STATS_TYPE
+
 #endif // SHRPX_H
index 2b6638a..8d02d74 100644 (file)
 #include "shrpx_connect_blocker.h"
 #include "shrpx_api_downstream_connection.h"
 #include "shrpx_health_monitor_downstream_connection.h"
+#include "shrpx_null_downstream_connection.h"
+#ifdef ENABLE_HTTP3
+#  include "shrpx_http3_upstream.h"
+#endif // ENABLE_HTTP3
 #include "shrpx_log.h"
 #include "util.h"
 #include "template.h"
@@ -285,6 +289,19 @@ int ClientHandler::write_tls() {
   }
 }
 
+#ifdef ENABLE_HTTP3
+int ClientHandler::read_quic(const UpstreamAddr *faddr,
+                             const Address &remote_addr,
+                             const Address &local_addr, const uint8_t *data,
+                             size_t datalen) {
+  auto upstream = static_cast<Http3Upstream *>(upstream_.get());
+
+  return upstream->on_read(faddr, remote_addr, local_addr, data, datalen);
+}
+
+int ClientHandler::write_quic() { return upstream_->on_write(); }
+#endif // ENABLE_HTTP3
+
 int ClientHandler::upstream_noop() { return 0; }
 
 int ClientHandler::upstream_read() {
@@ -401,7 +418,8 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
             get_config()->conn.upstream.ratelimit.write,
             get_config()->conn.upstream.ratelimit.read, writecb, readcb,
             timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold,
-            get_config()->tls.dyn_rec.idle_timeout, Proto::NONE),
+            get_config()->tls.dyn_rec.idle_timeout,
+            faddr->quic ? Proto::HTTP3 : Proto::NONE),
       ipaddr_(make_string_ref(balloc_, ipaddr)),
       port_(make_string_ref(balloc_, port)),
       faddr_(faddr),
@@ -417,19 +435,23 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
 
   reneg_shutdown_timer_.data = this;
 
-  conn_.rlimit.startw();
+  if (!faddr->quic) {
+    conn_.rlimit.startw();
+  }
   ev_timer_again(conn_.loop, &conn_.rt);
 
   auto config = get_config();
 
-  if (faddr_->accept_proxy_protocol ||
-      config->conn.upstream.accept_proxy_protocol) {
-    read_ = &ClientHandler::read_clear;
-    write_ = &ClientHandler::noop;
-    on_read_ = &ClientHandler::proxy_protocol_read;
-    on_write_ = &ClientHandler::upstream_noop;
-  } else {
-    setup_upstream_io_callback();
+  if (!faddr->quic) {
+    if (faddr_->accept_proxy_protocol ||
+        config->conn.upstream.accept_proxy_protocol) {
+      read_ = &ClientHandler::read_clear;
+      write_ = &ClientHandler::noop;
+      on_read_ = &ClientHandler::proxy_protocol_read;
+      on_write_ = &ClientHandler::upstream_noop;
+    } else {
+      setup_upstream_io_callback();
+    }
   }
 
   auto &fwdconf = config->http.forwarded;
@@ -491,6 +513,18 @@ void ClientHandler::setup_upstream_io_callback() {
   }
 }
 
+#ifdef ENABLE_HTTP3
+void ClientHandler::setup_http3_upstream(
+    std::unique_ptr<Http3Upstream> &&upstream) {
+  upstream_ = std::move(upstream);
+  write_ = &ClientHandler::write_quic;
+
+  auto config = get_config();
+
+  reset_upstream_read_timeout(config->conn.upstream.timeout.http3_read);
+}
+#endif // ENABLE_HTTP3
+
 ClientHandler::~ClientHandler() {
   if (LOG_ENABLED(INFO)) {
     CLOG(INFO, this) << "Deleting";
@@ -511,7 +545,8 @@ ClientHandler::~ClientHandler() {
 
   // TODO If backend is http/2, and it is in CONNECTED state, signal
   // it and make it loopbreak when output is zero.
-  if (worker_->get_graceful_shutdown() && worker_stat->num_connections == 0) {
+  if (worker_->get_graceful_shutdown() && worker_stat->num_connections == 0 &&
+      worker_stat->num_close_waits == 0) {
     ev_break(conn_.loop);
   }
 
@@ -902,10 +937,16 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream) {
   err = 0;
 
   switch (faddr_->alt_mode) {
-  case UpstreamAltMode::API:
-    return std::make_unique<APIDownstreamConnection>(worker_);
-  case UpstreamAltMode::HEALTHMON:
-    return std::make_unique<HealthMonitorDownstreamConnection>();
+  case UpstreamAltMode::API: {
+    auto dconn = std::make_unique<APIDownstreamConnection>(worker_);
+    dconn->set_client_handler(this);
+    return dconn;
+  }
+  case UpstreamAltMode::HEALTHMON: {
+    auto dconn = std::make_unique<HealthMonitorDownstreamConnection>();
+    dconn->set_client_handler(this);
+    return dconn;
+  }
   default:
     break;
   }
@@ -967,6 +1008,13 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream) {
   }
 
   auto &group = groups[group_idx];
+
+  if (group->shared_addr->dnf) {
+    auto dconn = std::make_unique<NullDownstreamConnection>(group);
+    dconn->set_client_handler(this);
+    return dconn;
+  }
+
   auto addr = get_downstream_addr(err, group.get(), downstream);
   if (addr == nullptr) {
     return nullptr;
@@ -979,6 +1027,14 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream) {
       return dconn;
     }
 
+    if (worker_->get_connect_blocker()->blocked()) {
+      if (LOG_ENABLED(INFO)) {
+        DCLOG(INFO, this)
+            << "Worker wide backend connection was blocked temporarily";
+      }
+      return nullptr;
+    }
+
     if (LOG_ENABLED(INFO)) {
       CLOG(INFO, this) << "Downstream connection pool is empty."
                        << " Create new one";
@@ -1542,4 +1598,13 @@ StringRef ClientHandler::get_alpn() const { return alpn_; }
 
 BlockAllocator &ClientHandler::get_block_allocator() { return balloc_; }
 
+void ClientHandler::set_alpn_from_conn() {
+  const unsigned char *alpn;
+  unsigned int alpnlen;
+
+  SSL_get0_alpn_selected(conn_.tls.ssl, &alpn, &alpnlen);
+
+  alpn_ = make_string_ref(balloc_, StringRef{alpn, alpnlen});
+}
+
 } // namespace shrpx
index bc56d48..f20adc9 100644 (file)
@@ -53,6 +53,9 @@ class Downstream;
 struct WorkerStat;
 struct DownstreamAddrGroup;
 struct DownstreamAddr;
+#ifdef ENABLE_HTTP3
+class Http3Upstream;
+#endif // ENABLE_HTTP3
 
 class ClientHandler {
 public:
@@ -143,6 +146,13 @@ public:
 
   void setup_upstream_io_callback();
 
+#ifdef ENABLE_HTTP3
+  void setup_http3_upstream(std::unique_ptr<Http3Upstream> &&upstream);
+  int read_quic(const UpstreamAddr *faddr, const Address &remote_addr,
+                const Address &local_addr, const uint8_t *data, size_t datalen);
+  int write_quic();
+#endif // ENABLE_HTTP3
+
   // Returns string suitable for use in "by" parameter of Forwarded
   // header field.
   StringRef get_forwarded_by() const;
@@ -177,6 +187,8 @@ public:
 
   BlockAllocator &get_block_allocator();
 
+  void set_alpn_from_conn();
+
 private:
   // Allocator to allocate memory for connection-wide objects.  Make
   // sure that the allocations must be bounded, and not proportional
index 769ad9b..b8acbe5 100644 (file)
@@ -230,10 +230,81 @@ read_tls_ticket_key_file(const std::vector<StringRef> &files,
   return ticket_keys;
 }
 
+#ifdef ENABLE_HTTP3
+std::shared_ptr<QUICKeyingMaterials>
+read_quic_secret_file(const StringRef &path) {
+  constexpr size_t expectedlen =
+      SHRPX_QUIC_SECRET_RESERVEDLEN + SHRPX_QUIC_SECRETLEN + SHRPX_QUIC_SALTLEN;
+
+  auto qkms = std::make_shared<QUICKeyingMaterials>();
+  auto &kms = qkms->keying_materials;
+
+  std::ifstream f(path.c_str());
+  if (!f) {
+    LOG(ERROR) << "frontend-quic-secret-file: could not open file " << path;
+    return nullptr;
+  }
+
+  std::array<char, 4096> buf;
+
+  while (f.getline(buf.data(), buf.size())) {
+    auto len = strlen(buf.data());
+    if (len == 0 || buf[0] == '#') {
+      continue;
+    }
+
+    auto s = StringRef{std::begin(buf), std::begin(buf) + len};
+    if (s.size() != expectedlen * 2 || !util::is_hex_string(s)) {
+      LOG(ERROR) << "frontend-quic-secret-file: each line must be a "
+                 << expectedlen * 2 << " bytes hex encoded string";
+      return nullptr;
+    }
+
+    kms.emplace_back();
+    auto &qkm = kms.back();
+
+    auto p = std::begin(s);
+
+    util::decode_hex(std::begin(qkm.reserved),
+                     StringRef{p, p + qkm.reserved.size()});
+    p += qkm.reserved.size() * 2;
+    util::decode_hex(std::begin(qkm.secret),
+                     StringRef{p, p + qkm.secret.size()});
+    p += qkm.secret.size() * 2;
+    util::decode_hex(std::begin(qkm.salt), StringRef{p, p + qkm.salt.size()});
+    p += qkm.salt.size() * 2;
+
+    assert(static_cast<size_t>(p - std::begin(s)) == expectedlen * 2);
+
+    qkm.id = qkm.reserved[0] & 0xc0;
+
+    if (kms.size() == 4) {
+      break;
+    }
+  }
+
+  if (f.bad() || (!f.eof() && f.fail())) {
+    LOG(ERROR)
+        << "frontend-quic-secret-file: error occurred while reading file "
+        << path;
+    return nullptr;
+  }
+
+  if (kms.empty()) {
+    LOG(WARN)
+        << "frontend-quic-secret-file: no keying materials are present in file "
+        << path;
+    return nullptr;
+  }
+
+  return qkms;
+}
+#endif // ENABLE_HTTP3
+
 FILE *open_file_for_write(const char *filename) {
   std::array<char, STRERROR_BUFSIZE> errbuf;
 
-#if defined O_CLOEXEC
+#ifdef O_CLOEXEC
   auto fd = open(filename, O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC,
                  S_IRUSR | S_IWUSR);
 #else
@@ -373,6 +444,57 @@ int parse_int(T *dest, const StringRef &opt, const char *optarg) {
 }
 
 namespace {
+int parse_altsvc(AltSvc &altsvc, const StringRef &opt,
+                 const StringRef &optarg) {
+  // PROTOID, PORT, HOST, ORIGIN, PARAMS.
+  auto tokens = util::split_str(optarg, ',', 5);
+
+  if (tokens.size() < 2) {
+    // Requires at least protocol_id and port
+    LOG(ERROR) << opt << ": too few parameters: " << optarg;
+    return -1;
+  }
+
+  int port;
+
+  if (parse_uint(&port, opt, tokens[1]) != 0) {
+    return -1;
+  }
+
+  if (port < 1 ||
+      port > static_cast<int>(std::numeric_limits<uint16_t>::max())) {
+    LOG(ERROR) << opt << ": port is invalid: " << tokens[1];
+    return -1;
+  }
+
+  altsvc.protocol_id = make_string_ref(config->balloc, tokens[0]);
+
+  altsvc.port = port;
+  altsvc.service = make_string_ref(config->balloc, tokens[1]);
+
+  if (tokens.size() > 2) {
+    if (!tokens[2].empty()) {
+      altsvc.host = make_string_ref(config->balloc, tokens[2]);
+    }
+
+    if (tokens.size() > 3) {
+      if (!tokens[3].empty()) {
+        altsvc.origin = make_string_ref(config->balloc, tokens[3]);
+      }
+
+      if (tokens.size() > 4) {
+        if (!tokens[4].empty()) {
+          altsvc.params = make_string_ref(config->balloc, tokens[4]);
+        }
+      }
+    }
+  }
+
+  return 0;
+}
+} // namespace
+
+namespace {
 // generated by gennghttpxfun.py
 LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
   switch (namelen) {
@@ -387,6 +509,11 @@ LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
     break;
   case 4:
     switch (name[3]) {
+    case 'h':
+      if (util::strieq_l("pat", name, 3)) {
+        return LogFragmentType::PATH;
+      }
+      break;
     case 'n':
       if (util::strieq_l("alp", name, 3)) {
         return LogFragmentType::ALPN;
@@ -396,6 +523,11 @@ LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
     break;
   case 6:
     switch (name[5]) {
+    case 'd':
+      if (util::strieq_l("metho", name, 5)) {
+        return LogFragmentType::METHOD;
+      }
+      break;
     case 's':
       if (util::strieq_l("statu", name, 5)) {
         return LogFragmentType::STATUS;
@@ -502,6 +634,15 @@ LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
       break;
     }
     break;
+  case 16:
+    switch (name[15]) {
+    case 'n':
+      if (util::strieq_l("protocol_versio", name, 15)) {
+        return LogFragmentType::PROTOCOL_VERSION;
+      }
+      break;
+    }
+    break;
   case 17:
     switch (name[16]) {
     case 'l':
@@ -521,6 +662,11 @@ LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
         return LogFragmentType::TLS_SESSION_REUSED;
       }
       break;
+    case 'y':
+      if (util::strieq_l("path_without_quer", name, 17)) {
+        return LogFragmentType::PATH_WITHOUT_QUERY;
+      }
+      break;
     }
     break;
   case 22:
@@ -761,6 +907,7 @@ struct UpstreamParams {
   bool tls;
   bool sni_fwd;
   bool proxyproto;
+  bool quic;
 };
 
 namespace {
@@ -795,6 +942,13 @@ int parse_upstream_params(UpstreamParams &out, const StringRef &src_params) {
       out.alt_mode = UpstreamAltMode::HEALTHMON;
     } else if (util::strieq_l("proxyproto", param)) {
       out.proxyproto = true;
+    } else if (util::strieq_l("quic", param)) {
+#ifdef ENABLE_HTTP3
+      out.quic = true;
+#else  // !ENABLE_HTTP3
+      LOG(ERROR) << "quic: QUIC is disabled at compile time";
+      return -1;
+#endif // !ENABLE_HTTP3
     } else if (!param.empty()) {
       LOG(ERROR) << "frontend: " << param << ": unknown keyword";
       return -1;
@@ -827,6 +981,7 @@ struct DownstreamParams {
   bool dns;
   bool redirect_if_not_tls;
   bool upgrade_scheme;
+  bool dnf;
 };
 
 namespace {
@@ -1001,6 +1156,8 @@ int parse_downstream_params(DownstreamParams &out,
         return -1;
       }
       out.group_weight = n;
+    } else if (util::strieq_l("dnf", param)) {
+      out.dnf = true;
     } else if (!param.empty()) {
       LOG(ERROR) << "backend: " << param << ": unknown keyword";
       return -1;
@@ -1065,6 +1222,7 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
   addr.sni = make_string_ref(downstreamconf.balloc, params.sni);
   addr.dns = params.dns;
   addr.upgrade_scheme = params.upgrade_scheme;
+  addr.dnf = params.dnf;
 
   auto &routerconf = downstreamconf.router;
   auto &router = routerconf.router;
@@ -1085,9 +1243,9 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
       *p = '\0';
       pattern = StringRef{iov.base, p};
     } else {
-      auto path = http2::normalize_path(downstreamconf.balloc,
-                                        StringRef{slash, std::end(raw_pattern)},
-                                        StringRef{});
+      auto path = http2::normalize_path_colon(
+          downstreamconf.balloc, StringRef{slash, std::end(raw_pattern)},
+          StringRef{});
       auto iov = make_byte_ref(downstreamconf.balloc,
                                std::distance(std::begin(raw_pattern), slash) +
                                    path.size() + 1);
@@ -1165,6 +1323,14 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
           return -1;
         }
       }
+      // All backends in the same group must have the same dnf
+      // setting.  If some backends do not specify dnf, and there is
+      // at least one backend with dnf, it is used for all backends in
+      // the group.  In general, multiple backends are not necessary
+      // for dnf because there is no need for load balancing.
+      if (params.dnf) {
+        g.dnf = true;
+      }
 
       g.addrs.push_back(addr);
       continue;
@@ -1189,6 +1355,7 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
     g.mruby_file = make_string_ref(downstreamconf.balloc, params.mruby);
     g.timeout.read = params.read_timeout;
     g.timeout.write = params.write_timeout;
+    g.dnf = params.dnf;
 
     if (pattern[0] == '*') {
       // wildcard pattern
@@ -1771,6 +1938,11 @@ int option_lookup_token(const char *name, size_t namelen) {
         return SHRPX_OPTID_SERVER_NAME;
       }
       break;
+    case 'f':
+      if (util::strieq_l("no-quic-bp", name, 10)) {
+        return SHRPX_OPTID_NO_QUIC_BPF;
+      }
+      break;
     case 'r':
       if (util::strieq_l("tls-sct-di", name, 10)) {
         return SHRPX_OPTID_TLS_SCT_DIR;
@@ -1814,6 +1986,11 @@ int option_lookup_token(const char *name, size_t namelen) {
         return SHRPX_OPTID_BACKEND_IPV6;
       }
       break;
+    case 'c':
+      if (util::strieq_l("http2-altsv", name, 11)) {
+        return SHRPX_OPTID_HTTP2_ALTSVC;
+      }
+      break;
     case 'e':
       if (util::strieq_l("host-rewrit", name, 11)) {
         return SHRPX_OPTID_HOST_REWRITE;
@@ -1877,6 +2054,11 @@ int option_lookup_token(const char *name, size_t namelen) {
     break;
   case 14:
     switch (name[13]) {
+    case 'd':
+      if (util::strieq_l("quic-server-i", name, 13)) {
+        return SHRPX_OPTID_QUIC_SERVER_ID;
+      }
+      break;
     case 'e':
       if (util::strieq_l("accesslog-fil", name, 13)) {
         return SHRPX_OPTID_ACCESSLOG_FILE;
@@ -1887,6 +2069,11 @@ int option_lookup_token(const char *name, size_t namelen) {
         return SHRPX_OPTID_NO_SERVER_PUSH;
       }
       break;
+    case 'k':
+      if (util::strieq_l("rlimit-memloc", name, 13)) {
+        return SHRPX_OPTID_RLIMIT_MEMLOCK;
+      }
+      break;
     case 'p':
       if (util::strieq_l("no-verify-ocs", name, 13)) {
         return SHRPX_OPTID_NO_VERIFY_OCSP;
@@ -2066,6 +2253,9 @@ int option_lookup_token(const char *name, size_t namelen) {
       }
       break;
     case 's':
+      if (util::strieq_l("max-worker-processe", name, 19)) {
+        return SHRPX_OPTID_MAX_WORKER_PROCESSES;
+      }
       if (util::strieq_l("tls13-client-cipher", name, 19)) {
         return SHRPX_OPTID_TLS13_CLIENT_CIPHERS;
       }
@@ -2095,6 +2285,11 @@ int option_lookup_token(const char *name, size_t namelen) {
         return SHRPX_OPTID_BACKEND_TLS_SNI_FIELD;
       }
       break;
+    case 'e':
+      if (util::strieq_l("quic-bpf-program-fil", name, 20)) {
+        return SHRPX_OPTID_QUIC_BPF_PROGRAM_FILE;
+      }
+      break;
     case 'l':
       if (util::strieq_l("accept-proxy-protoco", name, 20)) {
         return SHRPX_OPTID_ACCEPT_PROXY_PROTOCOL;
@@ -2144,6 +2339,9 @@ int option_lookup_token(const char *name, size_t namelen) {
       if (util::strieq_l("backend-request-buffe", name, 21)) {
         return SHRPX_OPTID_BACKEND_REQUEST_BUFFER;
       }
+      if (util::strieq_l("frontend-quic-qlog-di", name, 21)) {
+        return SHRPX_OPTID_FRONTEND_QUIC_QLOG_DIR;
+      }
       break;
     case 't':
       if (util::strieq_l("frontend-write-timeou", name, 21)) {
@@ -2167,6 +2365,11 @@ int option_lookup_token(const char *name, size_t namelen) {
         return SHRPX_OPTID_PRIVATE_KEY_PASSWD_FILE;
       }
       break;
+    case 'g':
+      if (util::strieq_l("frontend-quic-debug-lo", name, 22)) {
+        return SHRPX_OPTID_FRONTEND_QUIC_DEBUG_LOG;
+      }
+      break;
     case 'r':
       if (util::strieq_l("backend-response-buffe", name, 22)) {
         return SHRPX_OPTID_BACKEND_RESPONSE_BUFFER;
@@ -2181,6 +2384,11 @@ int option_lookup_token(const char *name, size_t namelen) {
     break;
   case 24:
     switch (name[23]) {
+    case 'a':
+      if (util::strieq_l("frontend-quic-early-dat", name, 23)) {
+        return SHRPX_OPTID_FRONTEND_QUIC_EARLY_DATA;
+      }
+      break;
     case 'd':
       if (util::strieq_l("strip-incoming-forwarde", name, 23)) {
         return SHRPX_OPTID_STRIP_INCOMING_FORWARDED;
@@ -2215,6 +2423,9 @@ int option_lookup_token(const char *name, size_t namelen) {
       if (util::strieq_l("backend-http2-window-siz", name, 24)) {
         return SHRPX_OPTID_BACKEND_HTTP2_WINDOW_SIZE;
       }
+      if (util::strieq_l("frontend-quic-secret-fil", name, 24)) {
+        return SHRPX_OPTID_FRONTEND_QUIC_SECRET_FILE;
+      }
       break;
     case 'g':
       if (util::strieq_l("http2-no-cookie-crumblin", name, 24)) {
@@ -2229,6 +2440,11 @@ int option_lookup_token(const char *name, size_t namelen) {
         return SHRPX_OPTID_MAX_REQUEST_HEADER_FIELDS;
       }
       break;
+    case 't':
+      if (util::strieq_l("frontend-quic-initial-rt", name, 24)) {
+        return SHRPX_OPTID_FRONTEND_QUIC_INITIAL_RTT;
+      }
+      break;
     }
     break;
   case 26:
@@ -2242,6 +2458,9 @@ int option_lookup_token(const char *name, size_t namelen) {
       if (util::strieq_l("frontend-http2-window-siz", name, 25)) {
         return SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_SIZE;
       }
+      if (util::strieq_l("frontend-http3-window-siz", name, 25)) {
+        return SHRPX_OPTID_FRONTEND_HTTP3_WINDOW_SIZE;
+      }
       break;
     case 's':
       if (util::strieq_l("frontend-http2-window-bit", name, 25)) {
@@ -2255,9 +2474,15 @@ int option_lookup_token(const char *name, size_t namelen) {
       if (util::strieq_l("backend-keep-alive-timeou", name, 25)) {
         return SHRPX_OPTID_BACKEND_KEEP_ALIVE_TIMEOUT;
       }
+      if (util::strieq_l("frontend-quic-idle-timeou", name, 25)) {
+        return SHRPX_OPTID_FRONTEND_QUIC_IDLE_TIMEOUT;
+      }
       if (util::strieq_l("no-http2-cipher-black-lis", name, 25)) {
         return SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST;
       }
+      if (util::strieq_l("no-http2-cipher-block-lis", name, 25)) {
+        return SHRPX_OPTID_NO_HTTP2_CIPHER_BLOCK_LIST;
+      }
       break;
     }
     break;
@@ -2268,6 +2493,11 @@ int option_lookup_token(const char *name, size_t namelen) {
         return SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED;
       }
       break;
+    case 'n':
+      if (util::strieq_l("frontend-quic-require-toke", name, 26)) {
+        return SHRPX_OPTID_FRONTEND_QUIC_REQUIRE_TOKEN;
+      }
+      break;
     case 'r':
       if (util::strieq_l("request-header-field-buffe", name, 26)) {
         return SHRPX_OPTID_REQUEST_HEADER_FIELD_BUFFER;
@@ -2282,6 +2512,9 @@ int option_lookup_token(const char *name, size_t namelen) {
       if (util::strieq_l("frontend-http2-read-timeou", name, 26)) {
         return SHRPX_OPTID_FRONTEND_HTTP2_READ_TIMEOUT;
       }
+      if (util::strieq_l("frontend-http3-read-timeou", name, 26)) {
+        return SHRPX_OPTID_FRONTEND_HTTP3_READ_TIMEOUT;
+      }
       if (util::strieq_l("frontend-keep-alive-timeou", name, 26)) {
         return SHRPX_OPTID_FRONTEND_KEEP_ALIVE_TIMEOUT;
       }
@@ -2327,6 +2560,11 @@ int option_lookup_token(const char *name, size_t namelen) {
         return SHRPX_OPTID_VERIFY_CLIENT_TOLERATE_EXPIRED;
       }
       break;
+    case 'e':
+      if (util::strieq_l("frontend-http3-max-window-siz", name, 29)) {
+        return SHRPX_OPTID_FRONTEND_HTTP3_MAX_WINDOW_SIZE;
+      }
+      break;
     case 'r':
       if (util::strieq_l("ignore-per-pattern-mruby-erro", name, 29)) {
         return SHRPX_OPTID_IGNORE_PER_PATTERN_MRUBY_ERROR;
@@ -2379,6 +2617,9 @@ int option_lookup_token(const char *name, size_t namelen) {
       if (util::strieq_l("client-no-http2-cipher-black-lis", name, 32)) {
         return SHRPX_OPTID_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST;
       }
+      if (util::strieq_l("client-no-http2-cipher-block-lis", name, 32)) {
+        return SHRPX_OPTID_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST;
+      }
       break;
     }
     break;
@@ -2422,11 +2663,19 @@ int option_lookup_token(const char *name, size_t namelen) {
       if (util::strieq_l("frontend-http2-dump-response-heade", name, 34)) {
         return SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER;
       }
+      if (util::strieq_l("frontend-quic-congestion-controlle", name, 34)) {
+        return SHRPX_OPTID_FRONTEND_QUIC_CONGESTION_CONTROLLER;
+      }
       break;
     }
     break;
   case 36:
     switch (name[35]) {
+    case 'd':
+      if (util::strieq_l("worker-process-grace-shutdown-perio", name, 35)) {
+        return SHRPX_OPTID_WORKER_PROCESS_GRACE_SHUTDOWN_PERIOD;
+      }
+      break;
     case 'e':
       if (util::strieq_l("backend-http2-connection-window-siz", name, 35)) {
         return SHRPX_OPTID_BACKEND_HTTP2_CONNECTION_WINDOW_SIZE;
@@ -2453,6 +2702,9 @@ int option_lookup_token(const char *name, size_t namelen) {
       if (util::strieq_l("frontend-http2-connection-window-siz", name, 36)) {
         return SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_SIZE;
       }
+      if (util::strieq_l("frontend-http3-connection-window-siz", name, 36)) {
+        return SHRPX_OPTID_FRONTEND_HTTP3_CONNECTION_WINDOW_SIZE;
+      }
       if (util::strieq_l("tls-session-cache-memcached-cert-fil", name, 36)) {
         return SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED_CERT_FILE;
       }
@@ -2464,6 +2716,9 @@ int option_lookup_token(const char *name, size_t namelen) {
       if (util::strieq_l("frontend-http2-max-concurrent-stream", name, 36)) {
         return SHRPX_OPTID_FRONTEND_HTTP2_MAX_CONCURRENT_STREAMS;
       }
+      if (util::strieq_l("frontend-http3-max-concurrent-stream", name, 36)) {
+        return SHRPX_OPTID_FRONTEND_HTTP3_MAX_CONCURRENT_STREAMS;
+      }
       break;
     }
     break;
@@ -2512,6 +2767,10 @@ int option_lookup_token(const char *name, size_t namelen) {
                          40)) {
         return SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WRITE_BUFFER_SIZE;
       }
+      if (util::strieq_l("frontend-http3-max-connection-window-siz", name,
+                         40)) {
+        return SHRPX_OPTID_FRONTEND_HTTP3_MAX_CONNECTION_WINDOW_SIZE;
+      }
       if (util::strieq_l("tls-ticket-key-memcached-private-key-fil", name,
                          40)) {
         return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_PRIVATE_KEY_FILE;
@@ -2594,7 +2853,6 @@ int parse_config(Config *config, int optid, const StringRef &opt,
     return 0;
   }
   case SHRPX_OPTID_FRONTEND: {
-    auto &listenerconf = config->conn.listener;
     auto &apiconf = config->api;
 
     auto addr_end = std::find(std::begin(optarg), std::end(optarg), ';');
@@ -2612,23 +2870,49 @@ int parse_config(Config *config, int optid, const StringRef &opt,
       return -1;
     }
 
+    if (params.quic) {
+      if (params.alt_mode != UpstreamAltMode::NONE) {
+        LOG(ERROR) << "frontend: api or healthmon cannot be used with quic";
+        return -1;
+      }
+
+      if (!params.tls) {
+        LOG(ERROR) << "frontend: quic requires TLS";
+        return -1;
+      }
+    }
+
     UpstreamAddr addr{};
     addr.fd = -1;
     addr.tls = params.tls;
     addr.sni_fwd = params.sni_fwd;
     addr.alt_mode = params.alt_mode;
     addr.accept_proxy_protocol = params.proxyproto;
+    addr.quic = params.quic;
 
     if (addr.alt_mode == UpstreamAltMode::API) {
       apiconf.enabled = true;
     }
 
+#ifdef ENABLE_HTTP3
+    auto &addrs = params.quic ? config->conn.quic_listener.addrs
+                              : config->conn.listener.addrs;
+#else  // !ENABLE_HTTP3
+    auto &addrs = config->conn.listener.addrs;
+#endif // !ENABLE_HTTP3
+
     if (util::istarts_with(optarg, SHRPX_UNIX_PATH_PREFIX)) {
+      if (addr.quic) {
+        LOG(ERROR) << "frontend: quic cannot be used on UNIX domain socket";
+        return -1;
+      }
+
       auto path = std::begin(optarg) + SHRPX_UNIX_PATH_PREFIX.size();
       addr.host = make_string_ref(config->balloc, StringRef{path, addr_end});
       addr.host_unix = true;
+      addr.index = addrs.size();
 
-      listenerconf.addrs.push_back(std::move(addr));
+      addrs.push_back(std::move(addr));
 
       return 0;
     }
@@ -2643,21 +2927,25 @@ int parse_config(Config *config, int optid, const StringRef &opt,
 
     if (util::numeric_host(host, AF_INET)) {
       addr.family = AF_INET;
-      listenerconf.addrs.push_back(std::move(addr));
+      addr.index = addrs.size();
+      addrs.push_back(std::move(addr));
       return 0;
     }
 
     if (util::numeric_host(host, AF_INET6)) {
       addr.family = AF_INET6;
-      listenerconf.addrs.push_back(std::move(addr));
+      addr.index = addrs.size();
+      addrs.push_back(std::move(addr));
       return 0;
     }
 
     addr.family = AF_INET;
-    listenerconf.addrs.push_back(addr);
+    addr.index = addrs.size();
+    addrs.push_back(addr);
 
     addr.family = AF_INET6;
-    listenerconf.addrs.push_back(std::move(addr));
+    addr.index = addrs.size();
+    addrs.push_back(std::move(addr));
 
     return 0;
   }
@@ -3106,45 +3394,10 @@ int parse_config(Config *config, int optid, const StringRef &opt,
   case SHRPX_OPTID_PADDING:
     return parse_uint(&config->padding, opt, optarg);
   case SHRPX_OPTID_ALTSVC: {
-    auto tokens = util::split_str(optarg, ',');
-
-    if (tokens.size() < 2) {
-      // Requires at least protocol_id and port
-      LOG(ERROR) << opt << ": too few parameters: " << optarg;
-      return -1;
-    }
-
-    if (tokens.size() > 4) {
-      // We only need protocol_id, port, host and origin
-      LOG(ERROR) << opt << ": too many parameters: " << optarg;
-      return -1;
-    }
-
-    int port;
-
-    if (parse_uint(&port, opt, tokens[1]) != 0) {
-      return -1;
-    }
-
-    if (port < 1 ||
-        port > static_cast<int>(std::numeric_limits<uint16_t>::max())) {
-      LOG(ERROR) << opt << ": port is invalid: " << tokens[1];
-      return -1;
-    }
-
     AltSvc altsvc{};
 
-    altsvc.protocol_id = make_string_ref(config->balloc, tokens[0]);
-
-    altsvc.port = port;
-    altsvc.service = make_string_ref(config->balloc, tokens[1]);
-
-    if (tokens.size() > 2) {
-      altsvc.host = make_string_ref(config->balloc, tokens[2]);
-
-      if (tokens.size() > 3) {
-        altsvc.origin = make_string_ref(config->balloc, tokens[3]);
-      }
+    if (parse_altsvc(altsvc, opt, optarg) != 0) {
+      return -1;
     }
 
     config->http.altsvcs.push_back(std::move(altsvc));
@@ -3463,8 +3716,11 @@ int parse_config(Config *config, int optid, const StringRef &opt,
     return 0;
   }
   case SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST:
-    config->tls.no_http2_cipher_black_list = util::strieq_l("yes", optarg);
-
+    LOG(WARN) << opt << ": deprecated.  Use "
+              << SHRPX_OPT_NO_HTTP2_CIPHER_BLOCK_LIST << " instead.";
+    // fall through
+  case SHRPX_OPTID_NO_HTTP2_CIPHER_BLOCK_LIST:
+    config->tls.no_http2_cipher_block_list = util::strieq_l("yes", optarg);
     return 0;
   case SHRPX_OPTID_BACKEND_HTTP1_TLS:
   case SHRPX_OPTID_BACKEND_TLS:
@@ -3666,7 +3922,11 @@ int parse_config(Config *config, int optid, const StringRef &opt,
     return 0;
 #endif // LIBRESSL_LEGACY_API
   case SHRPX_OPTID_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST:
-    config->tls.client.no_http2_cipher_black_list =
+    LOG(WARN) << opt << ": deprecated.  Use "
+              << SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST << " instead.";
+    // fall through
+  case SHRPX_OPTID_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST:
+    config->tls.client.no_http2_cipher_block_list =
         util::strieq_l("yes", optarg);
 
     return 0;
@@ -3694,7 +3954,7 @@ int parse_config(Config *config, int optid, const StringRef &opt,
                     "65535], inclusive";
       return -1;
     }
-    config->http.redirect_https_port = optarg;
+    config->http.redirect_https_port = make_string_ref(config->balloc, optarg);
     return 0;
   }
   case SHRPX_OPTID_FRONTEND_MAX_REQUESTS:
@@ -3742,6 +4002,168 @@ int parse_config(Config *config, int optid, const StringRef &opt,
     config->http.early_data.strip_incoming = !util::strieq_l("yes", optarg);
 
     return 0;
+  case SHRPX_OPTID_QUIC_BPF_PROGRAM_FILE:
+#ifdef ENABLE_HTTP3
+    config->quic.bpf.prog_file = make_string_ref(config->balloc, optarg);
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_NO_QUIC_BPF:
+#ifdef ENABLE_HTTP3
+    config->quic.bpf.disabled = util::strieq_l("yes", optarg);
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_HTTP2_ALTSVC: {
+    AltSvc altsvc{};
+
+    if (parse_altsvc(altsvc, opt, optarg) != 0) {
+      return -1;
+    }
+
+    config->http.http2_altsvcs.push_back(std::move(altsvc));
+
+    return 0;
+  }
+  case SHRPX_OPTID_FRONTEND_HTTP3_READ_TIMEOUT:
+#ifdef ENABLE_HTTP3
+    return parse_duration(&config->conn.upstream.timeout.http3_read, opt,
+                          optarg);
+#else  // !ENABLE_HTTP3
+    return 0;
+#endif // !ENABLE_HTTP3
+  case SHRPX_OPTID_FRONTEND_QUIC_IDLE_TIMEOUT:
+#ifdef ENABLE_HTTP3
+    return parse_duration(&config->quic.upstream.timeout.idle, opt, optarg);
+#else  // !ENABLE_HTTP3
+    return 0;
+#endif // !ENABLE_HTTP3
+  case SHRPX_OPTID_FRONTEND_QUIC_DEBUG_LOG:
+#ifdef ENABLE_HTTP3
+    config->quic.upstream.debug.log = util::strieq_l("yes", optarg);
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_FRONTEND_HTTP3_WINDOW_SIZE:
+#ifdef ENABLE_HTTP3
+    if (parse_uint_with_unit(&config->http3.upstream.window_size, opt,
+                             optarg) != 0) {
+      return -1;
+    }
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_FRONTEND_HTTP3_CONNECTION_WINDOW_SIZE:
+#ifdef ENABLE_HTTP3
+    if (parse_uint_with_unit(&config->http3.upstream.connection_window_size,
+                             opt, optarg) != 0) {
+      return -1;
+    }
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_FRONTEND_HTTP3_MAX_WINDOW_SIZE:
+#ifdef ENABLE_HTTP3
+    if (parse_uint_with_unit(&config->http3.upstream.max_window_size, opt,
+                             optarg) != 0) {
+      return -1;
+    }
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_FRONTEND_HTTP3_MAX_CONNECTION_WINDOW_SIZE:
+#ifdef ENABLE_HTTP3
+    if (parse_uint_with_unit(&config->http3.upstream.max_connection_window_size,
+                             opt, optarg) != 0) {
+      return -1;
+    }
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_FRONTEND_HTTP3_MAX_CONCURRENT_STREAMS:
+#ifdef ENABLE_HTTP3
+    return parse_uint(&config->http3.upstream.max_concurrent_streams, opt,
+                      optarg);
+#else  // !ENABLE_HTTP3
+    return 0;
+#endif // !ENABLE_HTTP3
+  case SHRPX_OPTID_FRONTEND_QUIC_EARLY_DATA:
+#ifdef ENABLE_HTTP3
+    config->quic.upstream.early_data = util::strieq_l("yes", optarg);
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_FRONTEND_QUIC_QLOG_DIR:
+#ifdef ENABLE_HTTP3
+    config->quic.upstream.qlog.dir = make_string_ref(config->balloc, optarg);
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_FRONTEND_QUIC_REQUIRE_TOKEN:
+#ifdef ENABLE_HTTP3
+    config->quic.upstream.require_token = util::strieq_l("yes", optarg);
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_FRONTEND_QUIC_CONGESTION_CONTROLLER:
+#ifdef ENABLE_HTTP3
+    if (util::strieq_l("cubic", optarg)) {
+      config->quic.upstream.congestion_controller = NGTCP2_CC_ALGO_CUBIC;
+    } else if (util::strieq_l("bbr", optarg)) {
+      config->quic.upstream.congestion_controller = NGTCP2_CC_ALGO_BBR;
+    } else {
+      LOG(ERROR) << opt << ": must be either cubic or bbr";
+      return -1;
+    }
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_QUIC_SERVER_ID:
+#ifdef ENABLE_HTTP3
+    if (optarg.size() != config->quic.server_id.size() * 2 ||
+        !util::is_hex_string(optarg)) {
+      LOG(ERROR) << opt << ": must be a hex-string";
+      return -1;
+    }
+    util::decode_hex(std::begin(config->quic.server_id), optarg);
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_FRONTEND_QUIC_SECRET_FILE:
+#ifdef ENABLE_HTTP3
+    config->quic.upstream.secret_file = make_string_ref(config->balloc, optarg);
+#endif // ENABLE_HTTP3
+
+    return 0;
+  case SHRPX_OPTID_RLIMIT_MEMLOCK: {
+    int n;
+
+    if (parse_uint(&n, opt, optarg) != 0) {
+      return -1;
+    }
+
+    if (n < 0) {
+      LOG(ERROR) << opt << ": specify the integer more than or equal to 0";
+
+      return -1;
+    }
+
+    config->rlimit_memlock = n;
+
+    return 0;
+  }
+  case SHRPX_OPTID_MAX_WORKER_PROCESSES:
+    return parse_uint(&config->max_worker_processes, opt, optarg);
+  case SHRPX_OPTID_WORKER_PROCESS_GRACE_SHUTDOWN_PERIOD:
+    return parse_duration(&config->worker_process_grace_shutdown_period, opt,
+                          optarg);
+  case SHRPX_OPTID_FRONTEND_QUIC_INITIAL_RTT: {
+#ifdef ENABLE_HTTP3
+    return parse_duration(&config->quic.upstream.initial_rtt, opt, optarg);
+#endif // ENABLE_HTTP3
+
+    return 0;
+  }
   case SHRPX_OPTID_CONF:
     LOG(WARN) << "conf: ignored";
 
@@ -3930,6 +4352,8 @@ StringRef strproto(Proto proto) {
     return StringRef::from_lit("http/1.1");
   case Proto::HTTP2:
     return StringRef::from_lit("h2");
+  case Proto::HTTP3:
+    return StringRef::from_lit("h3");
   case Proto::MEMCACHED:
     return StringRef::from_lit("memcached");
   }
@@ -4074,6 +4498,8 @@ int configure_downstream_group(Config *config, bool http2_proxy,
 
   auto resolve_flags = numeric_addr_only ? AI_NUMERICHOST | AI_NUMERICSERV : 0;
 
+  std::array<char, util::max_hostport> hostport_buf;
+
   for (auto &g : addr_groups) {
     std::unordered_map<StringRef, uint32_t> wgchk;
     for (auto &addr : g.addrs) {
@@ -4119,7 +4545,7 @@ int configure_downstream_group(Config *config, bool http2_proxy,
           util::make_http_hostport(downstreamconf.balloc, addr.host, addr.port);
 
       auto hostport =
-          util::make_hostport(downstreamconf.balloc, addr.host, addr.port);
+          util::make_hostport(std::begin(hostport_buf), addr.host, addr.port);
 
       if (!addr.dns) {
         if (resolve_hostname(&addr.addr, addr.host.c_str(), addr.port,
index ccc6b4a..d88ac7a 100644 (file)
@@ -51,6 +51,9 @@
 #include <nghttp2/nghttp2.h>
 
 #include "shrpx_router.h"
+#if ENABLE_HTTP3
+#  include "shrpx_quic.h"
+#endif // ENABLE_HTTP3
 #include "template.h"
 #include "http2.h"
 #include "network.h"
@@ -244,6 +247,8 @@ constexpr auto SHRPX_OPT_RESPONSE_HEADER_FIELD_BUFFER =
     StringRef::from_lit("response-header-field-buffer");
 constexpr auto SHRPX_OPT_MAX_RESPONSE_HEADER_FIELDS =
     StringRef::from_lit("max-response-header-fields");
+constexpr auto SHRPX_OPT_NO_HTTP2_CIPHER_BLOCK_LIST =
+    StringRef::from_lit("no-http2-cipher-block-list");
 constexpr auto SHRPX_OPT_NO_HTTP2_CIPHER_BLACK_LIST =
     StringRef::from_lit("no-http2-cipher-black-list");
 constexpr auto SHRPX_OPT_BACKEND_HTTP1_TLS =
@@ -322,6 +327,8 @@ constexpr auto SHRPX_OPT_FRONTEND_KEEP_ALIVE_TIMEOUT =
 constexpr auto SHRPX_OPT_PSK_SECRETS = StringRef::from_lit("psk-secrets");
 constexpr auto SHRPX_OPT_CLIENT_PSK_SECRETS =
     StringRef::from_lit("client-psk-secrets");
+constexpr auto SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST =
+    StringRef::from_lit("client-no-http2-cipher-block-list");
 constexpr auto SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST =
     StringRef::from_lit("client-no-http2-cipher-black-list");
 constexpr auto SHRPX_OPT_CLIENT_CIPHERS = StringRef::from_lit("client-ciphers");
@@ -356,6 +363,44 @@ constexpr auto SHRPX_OPT_TLS13_CLIENT_CIPHERS =
     StringRef::from_lit("tls13-client-ciphers");
 constexpr auto SHRPX_OPT_NO_STRIP_INCOMING_EARLY_DATA =
     StringRef::from_lit("no-strip-incoming-early-data");
+constexpr auto SHRPX_OPT_QUIC_BPF_PROGRAM_FILE =
+    StringRef::from_lit("quic-bpf-program-file");
+constexpr auto SHRPX_OPT_NO_QUIC_BPF = StringRef::from_lit("no-quic-bpf");
+constexpr auto SHRPX_OPT_HTTP2_ALTSVC = StringRef::from_lit("http2-altsvc");
+constexpr auto SHRPX_OPT_FRONTEND_HTTP3_READ_TIMEOUT =
+    StringRef::from_lit("frontend-http3-read-timeout");
+constexpr auto SHRPX_OPT_FRONTEND_QUIC_IDLE_TIMEOUT =
+    StringRef::from_lit("frontend-quic-idle-timeout");
+constexpr auto SHRPX_OPT_FRONTEND_QUIC_DEBUG_LOG =
+    StringRef::from_lit("frontend-quic-debug-log");
+constexpr auto SHRPX_OPT_FRONTEND_HTTP3_WINDOW_SIZE =
+    StringRef::from_lit("frontend-http3-window-size");
+constexpr auto SHRPX_OPT_FRONTEND_HTTP3_CONNECTION_WINDOW_SIZE =
+    StringRef::from_lit("frontend-http3-connection-window-size");
+constexpr auto SHRPX_OPT_FRONTEND_HTTP3_MAX_WINDOW_SIZE =
+    StringRef::from_lit("frontend-http3-max-window-size");
+constexpr auto SHRPX_OPT_FRONTEND_HTTP3_MAX_CONNECTION_WINDOW_SIZE =
+    StringRef::from_lit("frontend-http3-max-connection-window-size");
+constexpr auto SHRPX_OPT_FRONTEND_HTTP3_MAX_CONCURRENT_STREAMS =
+    StringRef::from_lit("frontend-http3-max-concurrent-streams");
+constexpr auto SHRPX_OPT_FRONTEND_QUIC_EARLY_DATA =
+    StringRef::from_lit("frontend-quic-early-data");
+constexpr auto SHRPX_OPT_FRONTEND_QUIC_QLOG_DIR =
+    StringRef::from_lit("frontend-quic-qlog-dir");
+constexpr auto SHRPX_OPT_FRONTEND_QUIC_REQUIRE_TOKEN =
+    StringRef::from_lit("frontend-quic-require-token");
+constexpr auto SHRPX_OPT_FRONTEND_QUIC_CONGESTION_CONTROLLER =
+    StringRef::from_lit("frontend-quic-congestion-controller");
+constexpr auto SHRPX_OPT_QUIC_SERVER_ID = StringRef::from_lit("quic-server-id");
+constexpr auto SHRPX_OPT_FRONTEND_QUIC_SECRET_FILE =
+    StringRef::from_lit("frontend-quic-secret-file");
+constexpr auto SHRPX_OPT_RLIMIT_MEMLOCK = StringRef::from_lit("rlimit-memlock");
+constexpr auto SHRPX_OPT_MAX_WORKER_PROCESSES =
+    StringRef::from_lit("max-worker-processes");
+constexpr auto SHRPX_OPT_WORKER_PROCESS_GRACE_SHUTDOWN_PERIOD =
+    StringRef::from_lit("worker-process-grace-shutdown-period");
+constexpr auto SHRPX_OPT_FRONTEND_QUIC_INITIAL_RTT =
+    StringRef::from_lit("frontend-quic-initial-rtt");
 
 constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
 
@@ -366,6 +411,7 @@ enum class Proto {
   NONE,
   HTTP1,
   HTTP2,
+  HTTP3,
   MEMCACHED,
 };
 
@@ -415,7 +461,7 @@ enum class ForwardedNode {
 };
 
 struct AltSvc {
-  StringRef protocol_id, host, origin, service;
+  StringRef protocol_id, host, origin, service, params;
 
   uint16_t port;
 };
@@ -430,6 +476,8 @@ enum class UpstreamAltMode {
 };
 
 struct UpstreamAddr {
+  // The unique index of this address.
+  size_t index;
   // The frontend address (e.g., FQDN, hostname, IP address).  If
   // |host_unix| is true, this is UNIX domain socket path.  This must
   // be NULL terminated string.
@@ -454,6 +502,7 @@ struct UpstreamAddr {
   bool sni_fwd;
   // true if client is supposed to send PROXY protocol v1 header.
   bool accept_proxy_protocol;
+  bool quic;
   int fd;
 };
 
@@ -490,6 +539,8 @@ struct DownstreamAddrConfig {
   // variant (e.g., "https") when forwarding request to a backend
   // connected by TLS connection.
   bool upgrade_scheme;
+  // true if a request should not be forwarded to a backend.
+  bool dnf;
 };
 
 // Mapping hash to idx which is an index into
@@ -506,6 +557,7 @@ struct DownstreamAddrGroupConfig {
       : pattern(pattern),
         affinity{SessionAffinity::NONE},
         redirect_if_not_tls(false),
+        dnf{false},
         timeout{} {}
 
   StringRef pattern;
@@ -519,6 +571,8 @@ struct DownstreamAddrGroupConfig {
   // true if this group requires that client connection must be TLS,
   // and the request must be redirected to https URI.
   bool redirect_if_not_tls;
+  // true if a request should not be forwarded to a backend.
+  bool dnf;
   // Timeouts for backend connection.
   struct {
     ev_tstamp read;
@@ -557,6 +611,22 @@ struct TLSCertificate {
   std::vector<uint8_t> sct_data;
 };
 
+#ifdef ENABLE_HTTP3
+struct QUICKeyingMaterial {
+  std::array<uint8_t, SHRPX_QUIC_SECRET_RESERVEDLEN> reserved;
+  std::array<uint8_t, SHRPX_QUIC_SECRETLEN> secret;
+  std::array<uint8_t, SHRPX_QUIC_SALTLEN> salt;
+  std::array<uint8_t, SHRPX_QUIC_CID_ENCRYPTION_KEYLEN> cid_encryption_key;
+  // Identifier of this keying material.  Only the first 2 bits are
+  // used.
+  uint8_t id;
+};
+
+struct QUICKeyingMaterials {
+  std::vector<QUICKeyingMaterial> keying_materials;
+};
+#endif // ENABLE_HTTP3
+
 struct HttpProxy {
   Address addr;
   // host in http proxy URI
@@ -652,7 +722,7 @@ struct TLSConfig {
     StringRef cert_file;
     StringRef ciphers;
     StringRef tls13_ciphers;
-    bool no_http2_cipher_black_list;
+    bool no_http2_cipher_block_list;
   } client;
 
   // PSK secrets.  The key is identity, and the associated value is
@@ -688,12 +758,48 @@ struct TLSConfig {
   int min_proto_version;
   int max_proto_version;
   bool insecure;
-  bool no_http2_cipher_black_list;
+  bool no_http2_cipher_block_list;
   // true if forwarding requests included in TLS early data should not
   // be postponed until TLS handshake finishes.
   bool no_postpone_early_data;
 };
 
+#ifdef ENABLE_HTTP3
+struct QUICConfig {
+  struct {
+    struct {
+      ev_tstamp idle;
+    } timeout;
+    struct {
+      bool log;
+    } debug;
+    struct {
+      StringRef dir;
+    } qlog;
+    ngtcp2_cc_algo congestion_controller;
+    bool early_data;
+    bool require_token;
+    StringRef secret_file;
+    ev_tstamp initial_rtt;
+  } upstream;
+  struct {
+    StringRef prog_file;
+    bool disabled;
+  } bpf;
+  std::array<uint8_t, SHRPX_QUIC_SERVER_IDLEN> server_id;
+};
+
+struct Http3Config {
+  struct {
+    size_t max_concurrent_streams;
+    int32_t window_size;
+    int32_t connection_window_size;
+    int32_t max_window_size;
+    int32_t max_connection_window_size;
+  } upstream;
+};
+#endif // ENABLE_HTTP3
+
 // custom error page
 struct ErrorPage {
   // not NULL-terminated
@@ -730,6 +836,11 @@ struct HttpConfig {
     bool strip_incoming;
   } early_data;
   std::vector<AltSvc> altsvcs;
+  // altsvcs serialized in a wire format.
+  StringRef altsvc_header_value;
+  std::vector<AltSvc> http2_altsvcs;
+  // http2_altsvcs serialized in a wire format.
+  StringRef http2_altsvc_header_value;
   std::vector<ErrorPage> error_pages;
   HeaderRefs add_request_headers;
   HeaderRefs add_response_headers;
@@ -899,9 +1010,16 @@ struct ConnectionConfig {
     int fastopen;
   } listener;
 
+#ifdef ENABLE_HTTP3
+  struct {
+    std::vector<UpstreamAddr> addrs;
+  } quic_listener;
+#endif // ENABLE_HTTP3
+
   struct {
     struct {
       ev_tstamp http2_read;
+      ev_tstamp http3_read;
       ev_tstamp read;
       ev_tstamp write;
       ev_tstamp idle_read;
@@ -942,6 +1060,9 @@ struct Config {
         http{},
         http2{},
         tls{},
+#ifdef ENABLE_HTTP3
+        quic{},
+#endif // ENABLE_HTTP3
         logging{},
         conn{},
         api{},
@@ -950,6 +1071,7 @@ struct Config {
         num_worker{0},
         padding{0},
         rlimit_nofile{0},
+        rlimit_memlock{0},
         uid{0},
         gid{0},
         pid{0},
@@ -959,7 +1081,10 @@ struct Config {
         single_process{false},
         single_thread{false},
         ignore_per_pattern_mruby_error{false},
-        ev_loop_flags{0} {}
+        ev_loop_flags{0},
+        max_worker_processes{0},
+        worker_process_grace_shutdown_period{0.} {
+  }
   ~Config();
 
   Config(Config &&) = delete;
@@ -975,6 +1100,10 @@ struct Config {
   HttpConfig http;
   Http2Config http2;
   TLSConfig tls;
+#ifdef ENABLE_HTTP3
+  QUICConfig quic;
+  Http3Config http3;
+#endif // ENABLE_HTTP3
   LoggingConfig logging;
   ConnectionConfig conn;
   APIConfig api;
@@ -993,6 +1122,7 @@ struct Config {
   size_t num_worker;
   size_t padding;
   size_t rlimit_nofile;
+  size_t rlimit_memlock;
   uid_t uid;
   gid_t gid;
   pid_t pid;
@@ -1007,6 +1137,8 @@ struct Config {
   bool ignore_per_pattern_mruby_error;
   // flags passed to ev_default_loop() and ev_loop_new()
   int ev_loop_flags;
+  size_t max_worker_processes;
+  ev_tstamp worker_process_grace_shutdown_period;
 };
 
 const Config *get_config();
@@ -1066,6 +1198,7 @@ enum {
   SHRPX_OPTID_CLIENT_CERT_FILE,
   SHRPX_OPTID_CLIENT_CIPHERS,
   SHRPX_OPTID_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST,
+  SHRPX_OPTID_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST,
   SHRPX_OPTID_CLIENT_PRIVATE_KEY_FILE,
   SHRPX_OPTID_CLIENT_PROXY,
   SHRPX_OPTID_CLIENT_PSK_SECRETS,
@@ -1098,13 +1231,28 @@ enum {
   SHRPX_OPTID_FRONTEND_HTTP2_SETTINGS_TIMEOUT,
   SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS,
   SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_SIZE,
+  SHRPX_OPTID_FRONTEND_HTTP3_CONNECTION_WINDOW_SIZE,
+  SHRPX_OPTID_FRONTEND_HTTP3_MAX_CONCURRENT_STREAMS,
+  SHRPX_OPTID_FRONTEND_HTTP3_MAX_CONNECTION_WINDOW_SIZE,
+  SHRPX_OPTID_FRONTEND_HTTP3_MAX_WINDOW_SIZE,
+  SHRPX_OPTID_FRONTEND_HTTP3_READ_TIMEOUT,
+  SHRPX_OPTID_FRONTEND_HTTP3_WINDOW_SIZE,
   SHRPX_OPTID_FRONTEND_KEEP_ALIVE_TIMEOUT,
   SHRPX_OPTID_FRONTEND_MAX_REQUESTS,
   SHRPX_OPTID_FRONTEND_NO_TLS,
+  SHRPX_OPTID_FRONTEND_QUIC_CONGESTION_CONTROLLER,
+  SHRPX_OPTID_FRONTEND_QUIC_DEBUG_LOG,
+  SHRPX_OPTID_FRONTEND_QUIC_EARLY_DATA,
+  SHRPX_OPTID_FRONTEND_QUIC_IDLE_TIMEOUT,
+  SHRPX_OPTID_FRONTEND_QUIC_INITIAL_RTT,
+  SHRPX_OPTID_FRONTEND_QUIC_QLOG_DIR,
+  SHRPX_OPTID_FRONTEND_QUIC_REQUIRE_TOKEN,
+  SHRPX_OPTID_FRONTEND_QUIC_SECRET_FILE,
   SHRPX_OPTID_FRONTEND_READ_TIMEOUT,
   SHRPX_OPTID_FRONTEND_WRITE_TIMEOUT,
   SHRPX_OPTID_HEADER_FIELD_BUFFER,
   SHRPX_OPTID_HOST_REWRITE,
+  SHRPX_OPTID_HTTP2_ALTSVC,
   SHRPX_OPTID_HTTP2_BRIDGE,
   SHRPX_OPTID_HTTP2_MAX_CONCURRENT_STREAMS,
   SHRPX_OPTID_HTTP2_NO_COOKIE_CRUMBLING,
@@ -1117,13 +1265,16 @@ enum {
   SHRPX_OPTID_MAX_HEADER_FIELDS,
   SHRPX_OPTID_MAX_REQUEST_HEADER_FIELDS,
   SHRPX_OPTID_MAX_RESPONSE_HEADER_FIELDS,
+  SHRPX_OPTID_MAX_WORKER_PROCESSES,
   SHRPX_OPTID_MRUBY_FILE,
   SHRPX_OPTID_NO_ADD_X_FORWARDED_PROTO,
   SHRPX_OPTID_NO_HOST_REWRITE,
   SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST,
+  SHRPX_OPTID_NO_HTTP2_CIPHER_BLOCK_LIST,
   SHRPX_OPTID_NO_KQUEUE,
   SHRPX_OPTID_NO_LOCATION_REWRITE,
   SHRPX_OPTID_NO_OCSP,
+  SHRPX_OPTID_NO_QUIC_BPF,
   SHRPX_OPTID_NO_SERVER_PUSH,
   SHRPX_OPTID_NO_SERVER_REWRITE,
   SHRPX_OPTID_NO_STRIP_INCOMING_EARLY_DATA,
@@ -1138,11 +1289,14 @@ enum {
   SHRPX_OPTID_PRIVATE_KEY_FILE,
   SHRPX_OPTID_PRIVATE_KEY_PASSWD_FILE,
   SHRPX_OPTID_PSK_SECRETS,
+  SHRPX_OPTID_QUIC_BPF_PROGRAM_FILE,
+  SHRPX_OPTID_QUIC_SERVER_ID,
   SHRPX_OPTID_READ_BURST,
   SHRPX_OPTID_READ_RATE,
   SHRPX_OPTID_REDIRECT_HTTPS_PORT,
   SHRPX_OPTID_REQUEST_HEADER_FIELD_BUFFER,
   SHRPX_OPTID_RESPONSE_HEADER_FIELD_BUFFER,
+  SHRPX_OPTID_RLIMIT_MEMLOCK,
   SHRPX_OPTID_RLIMIT_NOFILE,
   SHRPX_OPTID_SERVER_NAME,
   SHRPX_OPTID_SINGLE_PROCESS,
@@ -1183,6 +1337,7 @@ enum {
   SHRPX_OPTID_VERIFY_CLIENT_CACERT,
   SHRPX_OPTID_VERIFY_CLIENT_TOLERATE_EXPIRED,
   SHRPX_OPTID_WORKER_FRONTEND_CONNECTIONS,
+  SHRPX_OPTID_WORKER_PROCESS_GRACE_SHUTDOWN_PERIOD,
   SHRPX_OPTID_WORKER_READ_BURST,
   SHRPX_OPTID_WORKER_READ_RATE,
   SHRPX_OPTID_WORKER_WRITE_BURST,
@@ -1247,6 +1402,11 @@ std::unique_ptr<TicketKeys>
 read_tls_ticket_key_file(const std::vector<StringRef> &files,
                          const EVP_CIPHER *cipher, const EVP_MD *hmac);
 
+#ifdef ENABLE_HTTP3
+std::shared_ptr<QUICKeyingMaterials>
+read_quic_secret_file(const StringRef &path);
+#endif // ENABLE_HTTP3
+
 // Returns string representation of |proto|.
 StringRef strproto(Proto proto);
 
index 1937f45..af3cc05 100644 (file)
@@ -74,7 +74,7 @@ Connection::Connection(struct ev_loop *loop, int fd, SSL *ssl,
       read_timeout(read_timeout) {
 
   ev_io_init(&wev, writecb, fd, EV_WRITE);
-  ev_io_init(&rev, readcb, fd, EV_READ);
+  ev_io_init(&rev, readcb, proto == Proto::HTTP3 ? 0 : fd, EV_READ);
 
   wev.data = this;
   rev.data = this;
@@ -128,7 +128,7 @@ void Connection::disconnect() {
     tls.early_data_finish = false;
   }
 
-  if (fd != -1) {
+  if (proto != Proto::HTTP3 && fd != -1) {
     shutdown(fd, SHUT_WR);
     close(fd);
     fd = -1;
@@ -312,10 +312,13 @@ BIO_METHOD *create_bio_method() {
 void Connection::set_ssl(SSL *ssl) {
   tls.ssl = ssl;
 
-  auto &tlsconf = get_config()->tls;
-  auto bio = BIO_new(tlsconf.bio_method);
-  BIO_set_data(bio, this);
-  SSL_set_bio(tls.ssl, bio, bio);
+  if (proto != Proto::HTTP3) {
+    auto &tlsconf = get_config()->tls;
+    auto bio = BIO_new(tlsconf.bio_method);
+    BIO_set_data(bio, this);
+    SSL_set_bio(tls.ssl, bio, bio);
+  }
+
   SSL_set_app_data(tls.ssl, this);
 }
 
@@ -394,11 +397,14 @@ int Connection::tls_handshake() {
 
   ERR_clear_error();
 
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API || defined(OPENSSL_IS_BORINGSSL)
+  auto &tlsconf = get_config()->tls;
+#endif // OPENSSL_1_1_1_API || defined(OPENSSL_IS_BORINGSSL)
+
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
   if (!tls.server_handshake || tls.early_data_finish) {
     rv = SSL_do_handshake(tls.ssl);
   } else {
-    auto &tlsconf = get_config()->tls;
     for (;;) {
       size_t nread;
 
@@ -446,9 +452,9 @@ int Connection::tls_handshake() {
       }
     }
   }
-#else  // !OPENSSL_1_1_1_API
+#else  // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
   rv = SSL_do_handshake(tls.ssl);
-#endif // !OPENSSL_1_1_1_API
+#endif // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
 
   if (rv <= 0) {
     auto err = SSL_get_error(tls.ssl, rv);
@@ -496,7 +502,12 @@ int Connection::tls_handshake() {
   // Don't send handshake data if handshake was completed in OpenSSL
   // routine.  We have to check HTTP/2 requirement if HTTP/2 was
   // negotiated before sending finished message to the peer.
-  if (rv != 1 && tls.wbuf.rleft()) {
+  if ((rv != 1
+#ifdef OPENSSL_IS_BORINGSSL
+       || SSL_in_init(tls.ssl)
+#endif // OPENSSL_IS_BORINGSSL
+           ) &&
+      tls.wbuf.rleft()) {
     // First write indicates that resumption stuff has done.
     if (tls.handshake_state != TLSHandshakeState::WRITE_STARTED) {
       tls.handshake_state = TLSHandshakeState::WRITE_STARTED;
@@ -532,6 +543,40 @@ int Connection::tls_handshake() {
     return SHRPX_ERR_INPROGRESS;
   }
 
+#ifdef OPENSSL_IS_BORINGSSL
+  if (!tlsconf.no_postpone_early_data && SSL_in_early_data(tls.ssl) &&
+      SSL_in_init(tls.ssl)) {
+    auto nread = SSL_read(tls.ssl, buf.data(), buf.size());
+    if (nread <= 0) {
+      auto err = SSL_get_error(tls.ssl, nread);
+      switch (err) {
+      case SSL_ERROR_WANT_READ:
+      case SSL_ERROR_WANT_WRITE:
+        break;
+      case SSL_ERROR_ZERO_RETURN:
+        return SHRPX_ERR_EOF;
+      case SSL_ERROR_SSL:
+        if (LOG_ENABLED(INFO)) {
+          LOG(INFO) << "SSL_read: "
+                    << ERR_error_string(ERR_get_error(), nullptr);
+        }
+        return SHRPX_ERR_NETWORK;
+      default:
+        if (LOG_ENABLED(INFO)) {
+          LOG(INFO) << "SSL_read: SSL_get_error returned " << err;
+        }
+        return SHRPX_ERR_NETWORK;
+      }
+    } else {
+      tls.earlybuf.append(buf.data(), nread);
+    }
+
+    if (SSL_in_init(tls.ssl)) {
+      return SHRPX_ERR_INPROGRESS;
+    }
+  }
+#endif // OPENSSL_IS_BORINGSSL
+
   // Handshake was done
 
   rv = check_http2_requirement();
@@ -568,6 +613,36 @@ int Connection::write_tls_pending_handshake() {
     tls.wbuf.drain(nwrite);
   }
 
+#ifdef OPENSSL_IS_BORINGSSL
+  if (!SSL_in_init(tls.ssl)) {
+    // This will send a session ticket.
+    auto nwrite = SSL_write(tls.ssl, "", 0);
+    if (nwrite < 0) {
+      auto err = SSL_get_error(tls.ssl, nwrite);
+      switch (err) {
+      case SSL_ERROR_WANT_READ:
+        if (LOG_ENABLED(INFO)) {
+          LOG(INFO) << "Close connection due to TLS renegotiation";
+        }
+        return SHRPX_ERR_NETWORK;
+      case SSL_ERROR_WANT_WRITE:
+        break;
+      case SSL_ERROR_SSL:
+        if (LOG_ENABLED(INFO)) {
+          LOG(INFO) << "SSL_write: "
+                    << ERR_error_string(ERR_get_error(), nullptr);
+        }
+        return SHRPX_ERR_NETWORK;
+      default:
+        if (LOG_ENABLED(INFO)) {
+          LOG(INFO) << "SSL_write: SSL_get_error returned " << err;
+        }
+        return SHRPX_ERR_NETWORK;
+      }
+    }
+  }
+#endif // OPENSSL_IS_BORINGSSL
+
   // We have to start read watcher, since later stage of code expects
   // this.
   rlimit.startw();
@@ -616,18 +691,18 @@ int Connection::check_http2_requirement() {
     return -1;
   }
 
-  auto check_black_list = false;
+  auto check_block_list = false;
   if (tls.server_handshake) {
-    check_black_list = !get_config()->tls.no_http2_cipher_black_list;
+    check_block_list = !get_config()->tls.no_http2_cipher_block_list;
   } else {
-    check_black_list = !get_config()->tls.client.no_http2_cipher_black_list;
+    check_block_list = !get_config()->tls.client.no_http2_cipher_block_list;
   }
 
-  if (check_black_list &&
-      nghttp2::tls::check_http2_cipher_black_list(tls.ssl)) {
+  if (check_block_list &&
+      nghttp2::tls::check_http2_cipher_block_list(tls.ssl)) {
     if (LOG_ENABLED(INFO)) {
       LOG(INFO) << "The negotiated cipher suite is in HTTP/2 cipher suite "
-                   "black list.  HTTP/2 must not be used.";
+                   "block list.  HTTP/2 must not be used.";
     }
     return -1;
   }
@@ -695,7 +770,7 @@ ssize_t Connection::write_tls(const void *data, size_t len) {
 
   ERR_clear_error();
 
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
   int rv;
   if (SSL_is_init_finished(tls.ssl)) {
     rv = SSL_write(tls.ssl, data, len);
@@ -707,9 +782,9 @@ ssize_t Connection::write_tls(const void *data, size_t len) {
       rv = nwrite;
     }
   }
-#else  // !OPENSSL_1_1_1_API
+#else  // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
   auto rv = SSL_write(tls.ssl, data, len);
-#endif // !OPENSSL_1_1_1_API
+#endif // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
 
   if (rv <= 0) {
     auto err = SSL_get_error(tls.ssl, rv);
@@ -769,7 +844,7 @@ ssize_t Connection::read_tls(void *data, size_t len) {
     tls.last_readlen = 0;
   }
 
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
   if (!tls.early_data_finish) {
     // TLSv1.3 handshake is still going on.
     size_t nread;
@@ -808,7 +883,7 @@ ssize_t Connection::read_tls(void *data, size_t len) {
     }
     return nread;
   }
-#endif // OPENSSL_1_1_1_API
+#endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
 
   auto rv = SSL_read(tls.ssl, data, len);
 
index 84221ba..cf45f50 100644 (file)
@@ -45,6 +45,7 @@
 #include "shrpx_memcached_dispatcher.h"
 #include "shrpx_signal.h"
 #include "shrpx_log.h"
+#include "xsi_strerror.h"
 #include "util.h"
 #include "template.h"
 
@@ -112,7 +113,11 @@ void serial_event_async_cb(struct ev_loop *loop, ev_async *w, int revent) {
 } // namespace
 
 ConnectionHandler::ConnectionHandler(struct ev_loop *loop, std::mt19937 &gen)
-    : gen_(gen),
+    :
+#ifdef ENABLE_HTTP3
+      quic_ipc_fd_(-1),
+#endif // ENABLE_HTTP3
+      gen_(gen),
       single_worker_(nullptr),
       loop_(loop),
 #ifdef HAVE_NEVERBLEED
@@ -156,6 +161,19 @@ ConnectionHandler::~ConnectionHandler() {
   ev_timer_stop(loop_, &ocsp_timer_);
   ev_timer_stop(loop_, &disable_acceptor_timer_);
 
+#ifdef ENABLE_HTTP3
+  for (auto ssl_ctx : quic_all_ssl_ctx_) {
+    if (ssl_ctx == nullptr) {
+      continue;
+    }
+
+    auto tls_ctx_data =
+        static_cast<tls::TLSContextData *>(SSL_CTX_get_app_data(ssl_ctx));
+    delete tls_ctx_data;
+    SSL_CTX_free(ssl_ctx);
+  }
+#endif // ENABLE_HTTP3
+
   for (auto ssl_ctx : all_ssl_ctx_) {
     auto tls_ctx_data =
         static_cast<tls::TLSContextData *>(SSL_CTX_get_app_data(ssl_ctx));
@@ -179,24 +197,24 @@ void ConnectionHandler::set_ticket_keys_to_worker(
 }
 
 void ConnectionHandler::worker_reopen_log_files() {
-  WorkerEvent wev{};
+  for (auto &worker : workers_) {
+    WorkerEvent wev{};
 
-  wev.type = WorkerEventType::REOPEN_LOG;
+    wev.type = WorkerEventType::REOPEN_LOG;
 
-  for (auto &worker : workers_) {
-    worker->send(wev);
+    worker->send(std::move(wev));
   }
 }
 
 void ConnectionHandler::worker_replace_downstream(
     std::shared_ptr<DownstreamConfig> downstreamconf) {
-  WorkerEvent wev{};
+  for (auto &worker : workers_) {
+    WorkerEvent wev{};
 
-  wev.type = WorkerEventType::REPLACE_DOWNSTREAM;
-  wev.downstreamconf = std::move(downstreamconf);
+    wev.type = WorkerEventType::REPLACE_DOWNSTREAM;
+    wev.downstreamconf = downstreamconf;
 
-  for (auto &worker : workers_) {
-    worker->send(wev);
+    worker->send(std::move(wev));
   }
 }
 
@@ -209,6 +227,18 @@ int ConnectionHandler::create_single_worker() {
       nb_
 #endif // HAVE_NEVERBLEED
   );
+
+#ifdef ENABLE_HTTP3
+  quic_cert_tree_ = tls::create_cert_lookup_tree();
+  auto quic_sv_ssl_ctx = tls::setup_quic_server_ssl_context(
+      quic_all_ssl_ctx_, quic_indexed_ssl_ctx_, quic_cert_tree_.get()
+#  ifdef HAVE_NEVERBLEED
+                                                    ,
+      nb_
+#  endif // HAVE_NEVERBLEED
+  );
+#endif // ENABLE_HTTP3
+
   auto cl_ssl_ctx = tls::setup_downstream_client_ssl_context(
 #ifdef HAVE_NEVERBLEED
       nb_
@@ -217,6 +247,9 @@ int ConnectionHandler::create_single_worker() {
 
   if (cl_ssl_ctx) {
     all_ssl_ctx_.push_back(cl_ssl_ctx);
+#ifdef ENABLE_HTTP3
+    quic_all_ssl_ctx_.push_back(nullptr);
+#endif // ENABLE_HTTP3
   }
 
   auto config = get_config();
@@ -233,11 +266,30 @@ int ConnectionHandler::create_single_worker() {
           tlsconf.cacert, memcachedconf.cert_file,
           memcachedconf.private_key_file, nullptr);
       all_ssl_ctx_.push_back(session_cache_ssl_ctx);
+#ifdef ENABLE_HTTP3
+      quic_all_ssl_ctx_.push_back(nullptr);
+#endif // ENABLE_HTTP3
     }
   }
 
+#if defined(ENABLE_HTTP3) && defined(HAVE_LIBBPF)
+  quic_bpf_refs_.resize(config->conn.quic_listener.addrs.size());
+#endif // ENABLE_HTTP3 && HAVE_LIBBPF
+
+#ifdef ENABLE_HTTP3
+  assert(cid_prefixes_.size() == 1);
+  const auto &cid_prefix = cid_prefixes_[0];
+#endif // ENABLE_HTTP3
+
   single_worker_ = std::make_unique<Worker>(
       loop_, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(),
+#ifdef ENABLE_HTTP3
+      quic_sv_ssl_ctx, quic_cert_tree_.get(), cid_prefix.data(),
+      cid_prefix.size(),
+#  ifdef HAVE_LIBBPF
+      /* index = */ 0,
+#  endif // HAVE_LIBBPF
+#endif   // ENABLE_HTTP3
       ticket_keys_, this, config->conn.downstream);
 #ifdef HAVE_MRUBY
   if (single_worker_->create_mruby_context() != 0) {
@@ -245,6 +297,12 @@ int ConnectionHandler::create_single_worker() {
   }
 #endif // HAVE_MRUBY
 
+#ifdef ENABLE_HTTP3
+  if (single_worker_->setup_quic_server_socket() != 0) {
+    return -1;
+  }
+#endif // ENABLE_HTTP3
+
   return 0;
 }
 
@@ -260,6 +318,18 @@ int ConnectionHandler::create_worker_thread(size_t num) {
       nb_
 #  endif // HAVE_NEVERBLEED
   );
+
+#  ifdef ENABLE_HTTP3
+  quic_cert_tree_ = tls::create_cert_lookup_tree();
+  auto quic_sv_ssl_ctx = tls::setup_quic_server_ssl_context(
+      quic_all_ssl_ctx_, quic_indexed_ssl_ctx_, quic_cert_tree_.get()
+#    ifdef HAVE_NEVERBLEED
+                                                    ,
+      nb_
+#    endif // HAVE_NEVERBLEED
+  );
+#  endif // ENABLE_HTTP3
+
   auto cl_ssl_ctx = tls::setup_downstream_client_ssl_context(
 #  ifdef HAVE_NEVERBLEED
       nb_
@@ -268,12 +338,19 @@ int ConnectionHandler::create_worker_thread(size_t num) {
 
   if (cl_ssl_ctx) {
     all_ssl_ctx_.push_back(cl_ssl_ctx);
+#  ifdef ENABLE_HTTP3
+    quic_all_ssl_ctx_.push_back(nullptr);
+#  endif // ENABLE_HTTP3
   }
 
   auto config = get_config();
   auto &tlsconf = config->tls;
   auto &apiconf = config->api;
 
+#  if defined(ENABLE_HTTP3) && defined(HAVE_LIBBPF)
+  quic_bpf_refs_.resize(config->conn.quic_listener.addrs.size());
+#  endif // ENABLE_HTTP3 && HAVE_LIBBPF
+
   // We have dedicated worker for API request processing.
   if (apiconf.enabled) {
     ++num;
@@ -291,14 +368,32 @@ int ConnectionHandler::create_worker_thread(size_t num) {
           tlsconf.cacert, memcachedconf.cert_file,
           memcachedconf.private_key_file, nullptr);
       all_ssl_ctx_.push_back(session_cache_ssl_ctx);
+#  ifdef ENABLE_HTTP3
+      quic_all_ssl_ctx_.push_back(nullptr);
+#  endif // ENABLE_HTTP3
     }
   }
 
+#  ifdef ENABLE_HTTP3
+  assert(cid_prefixes_.size() == num);
+#  endif // ENABLE_HTTP3
+
   for (size_t i = 0; i < num; ++i) {
     auto loop = ev_loop_new(config->ev_loop_flags);
 
+#  ifdef ENABLE_HTTP3
+    const auto &cid_prefix = cid_prefixes_[i];
+#  endif // ENABLE_HTTP3
+
     auto worker = std::make_unique<Worker>(
         loop, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(),
+#  ifdef ENABLE_HTTP3
+        quic_sv_ssl_ctx, quic_cert_tree_.get(), cid_prefix.data(),
+        cid_prefix.size(),
+#    ifdef HAVE_LIBBPF
+        i,
+#    endif // HAVE_LIBBPF
+#  endif   // ENABLE_HTTP3
         ticket_keys_, this, config->conn.downstream);
 #  ifdef HAVE_MRUBY
     if (worker->create_mruby_context() != 0) {
@@ -306,6 +401,13 @@ int ConnectionHandler::create_worker_thread(size_t num) {
     }
 #  endif // HAVE_MRUBY
 
+#  ifdef ENABLE_HTTP3
+    if ((!apiconf.enabled || i != 0) &&
+        worker->setup_quic_server_socket() != 0) {
+      return -1;
+    }
+#  endif // ENABLE_HTTP3
+
     workers_.push_back(std::move(worker));
     worker_loops_.push_back(loop);
 
@@ -345,15 +447,15 @@ void ConnectionHandler::graceful_shutdown_worker() {
     return;
   }
 
-  WorkerEvent wev{};
-  wev.type = WorkerEventType::GRACEFUL_SHUTDOWN;
-
   if (LOG_ENABLED(INFO)) {
     LLOG(INFO, this) << "Sending graceful shutdown signal to worker";
   }
 
   for (auto &worker : workers_) {
-    worker->send(wev);
+    WorkerEvent wev{};
+    wev.type = WorkerEventType::GRACEFUL_SHUTDOWN;
+
+    worker->send(std::move(wev));
   }
 
 #ifndef NOTHREADS
@@ -436,7 +538,7 @@ int ConnectionHandler::handle_connection(int fd, sockaddr *addr, int addrlen,
   wev.client_addrlen = addrlen;
   wev.faddr = faddr;
 
-  worker->send(wev);
+  worker->send(std::move(wev));
 
   return 0;
 }
@@ -602,6 +704,9 @@ void ConnectionHandler::handle_ocsp_complete() {
   ev_child_stop(loop_, &ocsp_.chldev);
 
   assert(ocsp_.next < all_ssl_ctx_.size());
+#ifdef ENABLE_HTTP3
+  assert(all_ssl_ctx_.size() == quic_all_ssl_ctx_.size());
+#endif // ENABLE_HTTP3
 
   auto ssl_ctx = all_ssl_ctx_[ocsp_.next];
   auto tls_ctx_data =
@@ -629,6 +734,32 @@ void ConnectionHandler::handle_ocsp_complete() {
   if (tlsconf.ocsp.no_verify ||
       tls::verify_ocsp_response(ssl_ctx, ocsp_.resp.data(),
                                 ocsp_.resp.size()) == 0) {
+#ifdef ENABLE_HTTP3
+    // We have list of SSL_CTX with the same certificate in
+    // quic_all_ssl_ctx_ as well.  Some SSL_CTXs are missing there in
+    // that case we get nullptr.
+    auto quic_ssl_ctx = quic_all_ssl_ctx_[ocsp_.next];
+    if (quic_ssl_ctx) {
+#  ifndef OPENSSL_IS_BORINGSSL
+      auto quic_tls_ctx_data = static_cast<tls::TLSContextData *>(
+          SSL_CTX_get_app_data(quic_ssl_ctx));
+#    ifdef HAVE_ATOMIC_STD_SHARED_PTR
+      std::atomic_store_explicit(
+          &quic_tls_ctx_data->ocsp_data,
+          std::make_shared<std::vector<uint8_t>>(ocsp_.resp),
+          std::memory_order_release);
+#    else  // !HAVE_ATOMIC_STD_SHARED_PTR
+      std::lock_guard<std::mutex> g(quic_tls_ctx_data->mu);
+      quic_tls_ctx_data->ocsp_data =
+          std::make_shared<std::vector<uint8_t>>(ocsp_.resp);
+#    endif // !HAVE_ATOMIC_STD_SHARED_PTR
+#  else    // OPENSSL_IS_BORINGSSL
+      SSL_CTX_set_ocsp_response(quic_ssl_ctx, ocsp_.resp.data(),
+                                ocsp_.resp.size());
+#  endif   // OPENSSL_IS_BORINGSSL
+    }
+#endif // ENABLE_HTTP3
+
 #ifndef OPENSSL_IS_BORINGSSL
 #  ifdef HAVE_ATOMIC_STD_SHARED_PTR
     std::atomic_store_explicit(
@@ -809,6 +940,9 @@ SSL_CTX *ConnectionHandler::create_tls_ticket_key_memcached_ssl_ctx() {
       nullptr);
 
   all_ssl_ctx_.push_back(ssl_ctx);
+#ifdef ENABLE_HTTP3
+  quic_all_ssl_ctx_.push_back(nullptr);
+#endif // ENABLE_HTTP3
 
   return ssl_ctx;
 }
@@ -871,8 +1005,326 @@ ConnectionHandler::get_indexed_ssl_ctx(size_t idx) const {
   return indexed_ssl_ctx_[idx];
 }
 
+#ifdef ENABLE_HTTP3
+const std::vector<SSL_CTX *> &
+ConnectionHandler::get_quic_indexed_ssl_ctx(size_t idx) const {
+  return quic_indexed_ssl_ctx_[idx];
+}
+#endif // ENABLE_HTTP3
+
 void ConnectionHandler::set_enable_acceptor_on_ocsp_completion(bool f) {
   enable_acceptor_on_ocsp_completion_ = f;
 }
 
+#ifdef ENABLE_HTTP3
+int ConnectionHandler::forward_quic_packet(const UpstreamAddr *faddr,
+                                           const Address &remote_addr,
+                                           const Address &local_addr,
+                                           const uint8_t *cid_prefix,
+                                           const uint8_t *data,
+                                           size_t datalen) {
+  assert(!get_config()->single_thread);
+
+  for (auto &worker : workers_) {
+    if (!std::equal(cid_prefix, cid_prefix + SHRPX_QUIC_CID_PREFIXLEN,
+                    worker->get_cid_prefix())) {
+      continue;
+    }
+
+    WorkerEvent wev{};
+    wev.type = WorkerEventType::QUIC_PKT_FORWARD;
+    wev.quic_pkt = std::make_unique<QUICPacket>(faddr->index, remote_addr,
+                                                local_addr, data, datalen);
+
+    worker->send(std::move(wev));
+
+    return 0;
+  }
+
+  return -1;
+}
+
+void ConnectionHandler::set_quic_keying_materials(
+    std::shared_ptr<QUICKeyingMaterials> qkms) {
+  quic_keying_materials_ = std::move(qkms);
+}
+
+const std::shared_ptr<QUICKeyingMaterials> &
+ConnectionHandler::get_quic_keying_materials() const {
+  return quic_keying_materials_;
+}
+
+void ConnectionHandler::set_cid_prefixes(
+    const std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>>
+        &cid_prefixes) {
+  cid_prefixes_ = cid_prefixes;
+}
+
+QUICLingeringWorkerProcess *
+ConnectionHandler::match_quic_lingering_worker_process_cid_prefix(
+    const uint8_t *dcid, size_t dcidlen) {
+  assert(dcidlen >= SHRPX_QUIC_CID_PREFIXLEN);
+
+  for (auto &lwps : quic_lingering_worker_processes_) {
+    for (auto &cid_prefix : lwps.cid_prefixes) {
+      if (std::equal(std::begin(cid_prefix), std::end(cid_prefix), dcid)) {
+        return &lwps;
+      }
+    }
+  }
+
+  return nullptr;
+}
+
+#  ifdef HAVE_LIBBPF
+std::vector<BPFRef> &ConnectionHandler::get_quic_bpf_refs() {
+  return quic_bpf_refs_;
+}
+
+void ConnectionHandler::unload_bpf_objects() {
+  std::array<char, STRERROR_BUFSIZE> errbuf;
+
+  LOG(NOTICE) << "Unloading BPF objects";
+
+  for (auto &ref : quic_bpf_refs_) {
+    if (ref.obj == nullptr) {
+      continue;
+    }
+
+    if (bpf_object__unload(ref.obj) != 0) {
+      LOG(WARN) << "Failed to unload bpf object: "
+                << xsi_strerror(errno, errbuf.data(), errbuf.size());
+      continue;
+    }
+
+    ref.obj = nullptr;
+  }
+}
+#  endif // HAVE_LIBBPF
+
+void ConnectionHandler::set_quic_ipc_fd(int fd) { quic_ipc_fd_ = fd; }
+
+void ConnectionHandler::set_quic_lingering_worker_processes(
+    const std::vector<QUICLingeringWorkerProcess> &quic_lwps) {
+  quic_lingering_worker_processes_ = quic_lwps;
+}
+
+int ConnectionHandler::forward_quic_packet_to_lingering_worker_process(
+    QUICLingeringWorkerProcess *quic_lwp, const Address &remote_addr,
+    const Address &local_addr, const uint8_t *data, size_t datalen) {
+  std::array<uint8_t, 512> header;
+
+  assert(header.size() >= 1 + 1 + 1 + sizeof(sockaddr_storage) * 2);
+  assert(remote_addr.len > 0);
+  assert(local_addr.len > 0);
+
+  auto p = header.data();
+
+  *p++ = static_cast<uint8_t>(QUICIPCType::DGRAM_FORWARD);
+  *p++ = static_cast<uint8_t>(remote_addr.len - 1);
+  p = std::copy_n(reinterpret_cast<const uint8_t *>(&remote_addr.su),
+                  remote_addr.len, p);
+  *p++ = static_cast<uint8_t>(local_addr.len - 1);
+  p = std::copy_n(reinterpret_cast<const uint8_t *>(&local_addr.su),
+                  local_addr.len, p);
+
+  iovec msg_iov[] = {
+      {
+          .iov_base = header.data(),
+          .iov_len = static_cast<size_t>(p - header.data()),
+      },
+      {
+          .iov_base = const_cast<uint8_t *>(data),
+          .iov_len = datalen,
+      },
+  };
+
+  msghdr msg{};
+  msg.msg_iov = msg_iov;
+  msg.msg_iovlen = array_size(msg_iov);
+
+  ssize_t nwrite;
+
+  while ((nwrite = sendmsg(quic_lwp->quic_ipc_fd, &msg, 0)) == -1 &&
+         errno == EINTR)
+    ;
+
+  if (nwrite == -1) {
+    std::array<char, STRERROR_BUFSIZE> errbuf;
+
+    auto error = errno;
+    LOG(ERROR) << "Failed to send QUIC IPC message: "
+               << xsi_strerror(error, errbuf.data(), errbuf.size());
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int ConnectionHandler::quic_ipc_read() {
+  std::array<uint8_t, 65536> buf;
+
+  ssize_t nread;
+
+  while ((nread = recv(quic_ipc_fd_, buf.data(), buf.size(), 0)) == -1 &&
+         errno == EINTR)
+    ;
+
+  if (nread == -1) {
+    std::array<char, STRERROR_BUFSIZE> errbuf;
+
+    auto error = errno;
+    LOG(ERROR) << "Failed to read data from QUIC IPC channel: "
+               << xsi_strerror(error, errbuf.data(), errbuf.size());
+
+    return -1;
+  }
+
+  if (nread == 0) {
+    return 0;
+  }
+
+  size_t len = 1 + 1 + 1;
+
+  // Wire format:
+  // TYPE(1) REMOTE_ADDRLEN(1) REMOTE_ADDR(N) LOCAL_ADDRLEN(1) REMOTE_ADDR(N)
+  // DGRAM_PAYLAOD(N)
+  //
+  // When encoding, REMOTE_ADDRLEN and LOCAL_ADDRLEN is decremented by
+  // 1.
+  if (static_cast<size_t>(nread) < len) {
+    return 0;
+  }
+
+  auto p = buf.data();
+  if (*p != static_cast<uint8_t>(QUICIPCType::DGRAM_FORWARD)) {
+    LOG(ERROR) << "Unknown QUICIPCType: " << static_cast<uint32_t>(*p);
+
+    return -1;
+  }
+
+  ++p;
+
+  auto pkt = std::make_unique<QUICPacket>();
+
+  auto remote_addrlen = static_cast<size_t>(*p++) + 1;
+  if (remote_addrlen > sizeof(sockaddr_storage)) {
+    LOG(ERROR) << "The length of remote address is too large: "
+               << remote_addrlen;
+
+    return -1;
+  }
+
+  len += remote_addrlen;
+
+  if (static_cast<size_t>(nread) < len) {
+    LOG(ERROR) << "Insufficient QUIC IPC message length";
+
+    return -1;
+  }
+
+  pkt->remote_addr.len = remote_addrlen;
+  memcpy(&pkt->remote_addr.su, p, remote_addrlen);
+
+  p += remote_addrlen;
+
+  auto local_addrlen = static_cast<size_t>(*p++) + 1;
+  if (local_addrlen > sizeof(sockaddr_storage)) {
+    LOG(ERROR) << "The length of local address is too large: " << local_addrlen;
+
+    return -1;
+  }
+
+  len += local_addrlen;
+
+  if (static_cast<size_t>(nread) < len) {
+    LOG(ERROR) << "Insufficient QUIC IPC message length";
+
+    return -1;
+  }
+
+  pkt->local_addr.len = local_addrlen;
+  memcpy(&pkt->local_addr.su, p, local_addrlen);
+
+  p += local_addrlen;
+
+  auto datalen = nread - (p - buf.data());
+
+  pkt->data.assign(p, p + datalen);
+
+  // At the moment, UpstreamAddr index is unknown.
+  pkt->upstream_addr_index = static_cast<size_t>(-1);
+
+  uint32_t version;
+  const uint8_t *dcid;
+  size_t dcidlen;
+  const uint8_t *scid;
+  size_t scidlen;
+
+  auto rv =
+      ngtcp2_pkt_decode_version_cid(&version, &dcid, &dcidlen, &scid, &scidlen,
+                                    p, datalen, SHRPX_QUIC_SCIDLEN);
+  if (rv < 0) {
+    LOG(ERROR) << "ngtcp2_pkt_decode_version_cid: " << ngtcp2_strerror(rv);
+
+    return -1;
+  }
+
+  if (dcidlen != SHRPX_QUIC_SCIDLEN) {
+    LOG(ERROR) << "DCID length is invalid";
+    return -1;
+  }
+
+  if (single_worker_) {
+    auto faddr = single_worker_->find_quic_upstream_addr(pkt->local_addr);
+    if (faddr == nullptr) {
+      LOG(ERROR) << "No suitable upstream address found";
+
+      return 0;
+    }
+
+    auto quic_conn_handler = single_worker_->get_quic_connection_handler();
+
+    // Ignore return value
+    quic_conn_handler->handle_packet(faddr, pkt->remote_addr, pkt->local_addr,
+                                     pkt->data.data(), pkt->data.size());
+
+    return 0;
+  }
+
+  auto &qkm = quic_keying_materials_->keying_materials.front();
+
+  std::array<uint8_t, SHRPX_QUIC_DECRYPTED_DCIDLEN> decrypted_dcid;
+
+  if (decrypt_quic_connection_id(decrypted_dcid.data(),
+                                 dcid + SHRPX_QUIC_CID_PREFIX_OFFSET,
+                                 qkm.cid_encryption_key.data()) != 0) {
+    return -1;
+  }
+
+  for (auto &worker : workers_) {
+    if (!std::equal(std::begin(decrypted_dcid),
+                    std::begin(decrypted_dcid) + SHRPX_QUIC_CID_PREFIXLEN,
+                    worker->get_cid_prefix())) {
+      continue;
+    }
+
+    WorkerEvent wev{
+        .type = WorkerEventType::QUIC_PKT_FORWARD,
+        .quic_pkt = std::move(pkt),
+    };
+    worker->send(std::move(wev));
+
+    return 0;
+  }
+
+  if (LOG_ENABLED(INFO)) {
+    LOG(INFO) << "No worker to match CID prefix";
+  }
+
+  return 0;
+}
+#endif // ENABLE_HTTP3
+
 } // namespace shrpx
index 535bc2c..8bbf99c 100644 (file)
 #  include <future>
 #endif // NOTHREADS
 
+#ifdef HAVE_LIBBPF
+#  include <bpf/libbpf.h>
+#endif // HAVE_LIBBPF
+
 #include <openssl/ssl.h>
 
 #include <ev.h>
@@ -99,6 +103,35 @@ struct SerialEvent {
   std::shared_ptr<DownstreamConfig> downstreamconf;
 };
 
+#ifdef ENABLE_HTTP3
+#  ifdef HAVE_LIBBPF
+struct BPFRef {
+  bpf_object *obj;
+  int reuseport_array;
+  int cid_prefix_map;
+};
+#  endif // HAVE_LIBBPF
+
+// QUIC IPC message type.
+enum class QUICIPCType {
+  NONE,
+  // Send forwarded QUIC UDP datagram and its metadata.
+  DGRAM_FORWARD,
+};
+
+// WorkerProcesses which are in graceful shutdown period.
+struct QUICLingeringWorkerProcess {
+  QUICLingeringWorkerProcess(
+      std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes,
+      int quic_ipc_fd)
+      : cid_prefixes{std::move(cid_prefixes)}, quic_ipc_fd{quic_ipc_fd} {}
+
+  std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes;
+  // Socket to send QUIC IPC message to this worker process.
+  int quic_ipc_fd;
+};
+#endif // ENABLE_HTTP3
+
 class ConnectionHandler {
 public:
   ConnectionHandler(struct ev_loop *loop, std::mt19937 &gen);
@@ -159,6 +192,43 @@ public:
   SSL_CTX *get_ssl_ctx(size_t idx) const;
 
   const std::vector<SSL_CTX *> &get_indexed_ssl_ctx(size_t idx) const;
+#ifdef ENABLE_HTTP3
+  const std::vector<SSL_CTX *> &get_quic_indexed_ssl_ctx(size_t idx) const;
+
+  int forward_quic_packet(const UpstreamAddr *faddr, const Address &remote_addr,
+                          const Address &local_addr, const uint8_t *cid_prefix,
+                          const uint8_t *data, size_t datalen);
+
+  void set_quic_keying_materials(std::shared_ptr<QUICKeyingMaterials> qkms);
+  const std::shared_ptr<QUICKeyingMaterials> &get_quic_keying_materials() const;
+
+  void set_cid_prefixes(
+      const std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>>
+          &cid_prefixes);
+
+  void set_quic_lingering_worker_processes(
+      const std::vector<QUICLingeringWorkerProcess> &quic_lwps);
+
+  // Return matching QUICLingeringWorkerProcess which has a CID prefix
+  // such that |dcid| starts with it.  If no such
+  // QUICLingeringWorkerProcess, it returns nullptr.
+  QUICLingeringWorkerProcess *
+  match_quic_lingering_worker_process_cid_prefix(const uint8_t *dcid,
+                                                 size_t dcidlen);
+
+  int forward_quic_packet_to_lingering_worker_process(
+      QUICLingeringWorkerProcess *quic_lwp, const Address &remote_addr,
+      const Address &local_addr, const uint8_t *data, size_t datalen);
+
+  void set_quic_ipc_fd(int fd);
+
+  int quic_ipc_read();
+
+#  ifdef HAVE_LIBBPF
+  std::vector<BPFRef> &get_quic_bpf_refs();
+  void unload_bpf_objects();
+#  endif // HAVE_LIBBPF
+#endif   // ENABLE_HTTP3
 
 #ifdef HAVE_NEVERBLEED
   void set_neverbleed(neverbleed_t *nb);
@@ -187,6 +257,19 @@ private:
   // selection among them are performed by hostname presented by SNI,
   // and signature algorithm presented by client.
   std::vector<std::vector<SSL_CTX *>> indexed_ssl_ctx_;
+#ifdef ENABLE_HTTP3
+  std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes_;
+  std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>>
+      lingering_cid_prefixes_;
+  int quic_ipc_fd_;
+  std::vector<QUICLingeringWorkerProcess> quic_lingering_worker_processes_;
+#  ifdef HAVE_LIBBPF
+  std::vector<BPFRef> quic_bpf_refs_;
+#  endif // HAVE_LIBBPF
+  std::shared_ptr<QUICKeyingMaterials> quic_keying_materials_;
+  std::vector<SSL_CTX *> quic_all_ssl_ctx_;
+  std::vector<std::vector<SSL_CTX *>> quic_indexed_ssl_ctx_;
+#endif // ENABLE_HTTP3
   OCSPUpdateContext ocsp_;
   std::mt19937 &gen_;
   // ev_loop for each worker
@@ -203,6 +286,9 @@ private:
   // Otherwise, nullptr and workers_ has instances of Worker instead.
   std::unique_ptr<Worker> single_worker_;
   std::unique_ptr<tls::CertLookupTree> cert_tree_;
+#ifdef ENABLE_HTTP3
+  std::unique_ptr<tls::CertLookupTree> quic_cert_tree_;
+#endif // ENABLE_HTTP3
   std::unique_ptr<MemcachedDispatcher> tls_ticket_key_memcached_dispatcher_;
   // Current TLS session ticket keys.  Note that TLS connection does
   // not refer to this field directly.  They use TicketKeys object in
index dc7762d..245e00b 100644 (file)
@@ -113,7 +113,7 @@ void downstream_wtimeoutcb(struct ev_loop *loop, ev_timer *w, int revents) {
 
 // upstream could be nullptr for unittests
 Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool,
-                       int32_t stream_id)
+                       int64_t stream_id)
     : dlnext(nullptr),
       dlprev(nullptr),
       response_sent_body_length(0),
@@ -145,7 +145,8 @@ Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool,
       accesslog_written_(false),
       new_affinity_cookie_(false),
       blocked_request_data_eof_(false),
-      expect_100_continue_(false) {
+      expect_100_continue_(false),
+      stop_reading_(false) {
 
   auto &timeoutconf = get_config()->http2.timeout;
 
@@ -164,6 +165,9 @@ Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool,
   downstream_wtimer_.data = this;
 
   rcbufs_.reserve(32);
+#ifdef ENABLE_HTTP3
+  rcbufs3_.reserve(32);
+#endif // ENABLE_HTTP3
 }
 
 Downstream::~Downstream() {
@@ -203,6 +207,12 @@ Downstream::~Downstream() {
   // explicitly.
   dconn_.reset();
 
+#ifdef ENABLE_HTTP3
+  for (auto rcbuf : rcbufs3_) {
+    nghttp3_rcbuf_decref(rcbuf);
+  }
+#endif // ENABLE_HTTP3
+
   for (auto rcbuf : rcbufs_) {
     nghttp2_rcbuf_decref(rcbuf);
   }
@@ -605,9 +615,9 @@ void Downstream::reset_upstream(Upstream *upstream) {
 
 Upstream *Downstream::get_upstream() const { return upstream_; }
 
-void Downstream::set_stream_id(int32_t stream_id) { stream_id_ = stream_id; }
+void Downstream::set_stream_id(int64_t stream_id) { stream_id_ = stream_id; }
 
-int32_t Downstream::get_stream_id() const { return stream_id_; }
+int64_t Downstream::get_stream_id() const { return stream_id_; }
 
 void Downstream::set_request_state(DownstreamState state) {
   request_state_ = state;
@@ -886,7 +896,8 @@ bool Downstream::get_non_final_response() const {
 }
 
 bool Downstream::supports_non_final_response() const {
-  return req_.http_major == 2 || (req_.http_major == 1 && req_.http_minor == 1);
+  return req_.http_major == 3 || req_.http_major == 2 ||
+         (req_.http_major == 1 && req_.http_minor == 1);
 }
 
 bool Downstream::get_upgraded() const { return upgraded_; }
@@ -904,11 +915,11 @@ StringRef Downstream::get_http2_settings() const {
   return http2_settings->value;
 }
 
-void Downstream::set_downstream_stream_id(int32_t stream_id) {
+void Downstream::set_downstream_stream_id(int64_t stream_id) {
   downstream_stream_id_ = stream_id;
 }
 
-int32_t Downstream::get_downstream_stream_id() const {
+int64_t Downstream::get_downstream_stream_id() const {
   return downstream_stream_id_;
 }
 
@@ -937,7 +948,8 @@ bool Downstream::expect_response_trailer() const {
   // In HTTP/2, if final response HEADERS does not bear END_STREAM it
   // is possible trailer fields might come, regardless of request
   // method or status code.
-  return !resp_.headers_only && resp_.http_major == 2;
+  return !resp_.headers_only &&
+         (resp_.http_major == 3 || resp_.http_major == 2);
 }
 
 namespace {
@@ -1115,11 +1127,11 @@ DefaultMemchunks Downstream::pop_response_buf() {
   return std::move(response_buf_);
 }
 
-void Downstream::set_assoc_stream_id(int32_t stream_id) {
+void Downstream::set_assoc_stream_id(int64_t stream_id) {
   assoc_stream_id_ = stream_id;
 }
 
-int32_t Downstream::get_assoc_stream_id() const { return assoc_stream_id_; }
+int64_t Downstream::get_assoc_stream_id() const { return assoc_stream_id_; }
 
 BlockAllocator &Downstream::get_block_allocator() { return balloc_; }
 
@@ -1128,6 +1140,13 @@ void Downstream::add_rcbuf(nghttp2_rcbuf *rcbuf) {
   rcbufs_.push_back(rcbuf);
 }
 
+#ifdef ENABLE_HTTP3
+void Downstream::add_rcbuf(nghttp3_rcbuf *rcbuf) {
+  nghttp3_rcbuf_incref(rcbuf);
+  rcbufs3_.push_back(rcbuf);
+}
+#endif // ENABLE_HTTP3
+
 void Downstream::set_downstream_addr_group(
     const std::shared_ptr<DownstreamAddrGroup> &group) {
   group_ = group;
@@ -1169,4 +1188,8 @@ bool Downstream::get_expect_100_continue() const {
   return expect_100_continue_;
 }
 
+bool Downstream::get_stop_reading() const { return stop_reading_; }
+
+void Downstream::set_stop_reading(bool f) { stop_reading_ = f; }
+
 } // namespace shrpx
index fff49a1..2a50a97 100644 (file)
 
 #include <nghttp2/nghttp2.h>
 
+#ifdef ENABLE_HTTP3
+#  include <nghttp3/nghttp3.h>
+#endif // ENABLE_HTTP3
+
 #include "llhttp.h"
 
 #include "shrpx_io_control.h"
@@ -319,20 +323,20 @@ enum class DispatchState {
 
 class Downstream {
 public:
-  Downstream(Upstream *upstream, MemchunkPool *mcpool, int32_t stream_id);
+  Downstream(Upstream *upstream, MemchunkPool *mcpool, int64_t stream_id);
   ~Downstream();
   void reset_upstream(Upstream *upstream);
   Upstream *get_upstream() const;
-  void set_stream_id(int32_t stream_id);
-  int32_t get_stream_id() const;
-  void set_assoc_stream_id(int32_t stream_id);
-  int32_t get_assoc_stream_id() const;
+  void set_stream_id(int64_t stream_id);
+  int64_t get_stream_id() const;
+  void set_assoc_stream_id(int64_t stream_id);
+  int64_t get_assoc_stream_id() const;
   void pause_read(IOCtrlReason reason);
   int resume_read(IOCtrlReason reason, size_t consumed);
   void force_resume_read();
   // Set stream ID for downstream HTTP2 connection.
-  void set_downstream_stream_id(int32_t stream_id);
-  int32_t get_downstream_stream_id() const;
+  void set_downstream_stream_id(int64_t stream_id);
+  int64_t get_downstream_stream_id() const;
 
   int attach_downstream_connection(std::unique_ptr<DownstreamConnection> dconn);
   void detach_downstream_connection();
@@ -488,6 +492,9 @@ public:
   BlockAllocator &get_block_allocator();
 
   void add_rcbuf(nghttp2_rcbuf *rcbuf);
+#ifdef ENABLE_HTTP3
+  void add_rcbuf(nghttp3_rcbuf *rcbuf);
+#endif // ENABLE_HTTP3
 
   void
   set_downstream_addr_group(const std::shared_ptr<DownstreamAddrGroup> &group);
@@ -513,6 +520,9 @@ public:
 
   bool get_expect_100_continue() const;
 
+  bool get_stop_reading() const;
+  void set_stop_reading(bool f);
+
   enum {
     EVENT_ERROR = 0x1,
     EVENT_TIMEOUT = 0x2,
@@ -527,6 +537,9 @@ private:
   BlockAllocator balloc_;
 
   std::vector<nghttp2_rcbuf *> rcbufs_;
+#ifdef ENABLE_HTTP3
+  std::vector<nghttp3_rcbuf *> rcbufs3_;
+#endif // ENABLE_HTTP3
 
   Request req_;
   Response resp_;
@@ -566,12 +579,12 @@ private:
   // How many times we tried in backend connection
   size_t num_retry_;
   // The stream ID in frontend connection
-  int32_t stream_id_;
+  int64_t stream_id_;
   // The associated stream ID in frontend connection if this is pushed
   // stream.
-  int32_t assoc_stream_id_;
+  int64_t assoc_stream_id_;
   // stream ID in backend connection
-  int32_t downstream_stream_id_;
+  int64_t downstream_stream_id_;
   // RST_STREAM error_code from downstream HTTP2 connection
   uint32_t response_rst_stream_error_code_;
   // An affinity cookie value.
@@ -606,6 +619,7 @@ private:
   bool blocked_request_data_eof_;
   // true if request contains "expect: 100-continue" header field.
   bool expect_100_continue_;
+  bool stop_reading_;
 };
 
 } // namespace shrpx
index 9851443..6100b18 100644 (file)
@@ -168,6 +168,11 @@ void test_downstream_supports_non_final_response(void) {
   Downstream d(nullptr, nullptr, 0);
   auto &req = d.request();
 
+  req.http_major = 3;
+  req.http_minor = 0;
+
+  CU_ASSERT(d.supports_non_final_response());
+
   req.http_major = 2;
   req.http_minor = 0;
 
index 69bc323..0627250 100644 (file)
@@ -220,6 +220,57 @@ bool require_cookie_secure_attribute(SessionAffinityCookieSecure secure,
   }
 }
 
+StringRef create_altsvc_header_value(BlockAllocator &balloc,
+                                     const std::vector<AltSvc> &altsvcs) {
+  // <PROTOID>="<HOST>:<SERVICE>"; <PARAMS>
+  size_t len = 0;
+
+  if (altsvcs.empty()) {
+    return StringRef{};
+  }
+
+  for (auto &altsvc : altsvcs) {
+    len += util::percent_encode_tokenlen(altsvc.protocol_id);
+    len += str_size("=\"");
+    len += util::quote_stringlen(altsvc.host);
+    len += str_size(":");
+    len += altsvc.service.size();
+    len += str_size("\"");
+    if (!altsvc.params.empty()) {
+      len += str_size("; ");
+      len += altsvc.params.size();
+    }
+  }
+
+  // ", " between items.
+  len += (altsvcs.size() - 1) * 2;
+
+  // We will write additional ", " at the end, and cut it later.
+  auto iov = make_byte_ref(balloc, len + 2);
+  auto p = iov.base;
+
+  for (auto &altsvc : altsvcs) {
+    p = util::percent_encode_token(p, altsvc.protocol_id);
+    p = util::copy_lit(p, "=\"");
+    p = util::quote_string(p, altsvc.host);
+    *p++ = ':';
+    p = std::copy(std::begin(altsvc.service), std::end(altsvc.service), p);
+    *p++ = '"';
+    if (!altsvc.params.empty()) {
+      p = util::copy_lit(p, "; ");
+      p = std::copy(std::begin(altsvc.params), std::end(altsvc.params), p);
+    }
+    p = util::copy_lit(p, ", ");
+  }
+
+  p -= 2;
+  *p = '\0';
+
+  assert(static_cast<size_t>(p - iov.base) == len);
+
+  return StringRef{iov.base, p};
+}
+
 } // namespace http
 
 } // namespace shrpx
index 37be7e1..7b9cbb1 100644 (file)
@@ -79,6 +79,10 @@ StringRef create_affinity_cookie(BlockAllocator &balloc, const StringRef &name,
 bool require_cookie_secure_attribute(SessionAffinityCookieSecure secure,
                                      const StringRef &scheme);
 
+// Returns RFC 7838 alt-svc header field value.
+StringRef create_altsvc_header_value(BlockAllocator &balloc,
+                                     const std::vector<AltSvc> &altsvcs);
+
 } // namespace http
 
 } // namespace shrpx
index 6043a9d..2f9d2e5 100644 (file)
@@ -2379,6 +2379,10 @@ void Http2Session::check_retire() {
 
   ev_prepare_stop(conn_.loop, &prep_);
 
+  if (!session_) {
+    return;
+  }
+
   auto last_stream_id = nghttp2_session_get_last_proc_stream_id(session_);
   nghttp2_submit_goaway(session_, NGHTTP2_FLAG_NONE, last_stream_id,
                         NGHTTP2_NO_ERROR, nullptr, 0);
index 9b9e552..5f8b525 100644 (file)
@@ -1070,13 +1070,12 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
                       << nghttp2_strerror(rv);
   }
 
-  auto window_size =
-      faddr->alt_mode != UpstreamAltMode::NONE
-          ? std::numeric_limits<int32_t>::max()
-          : http2conf.upstream.optimize_window_size
-                ? std::min(http2conf.upstream.connection_window_size,
-                           NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE)
-                : http2conf.upstream.connection_window_size;
+  auto window_size = faddr->alt_mode != UpstreamAltMode::NONE
+                         ? std::numeric_limits<int32_t>::max()
+                     : http2conf.upstream.optimize_window_size
+                         ? std::min(http2conf.upstream.connection_window_size,
+                                    NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE)
+                         : http2conf.upstream.connection_window_size;
 
   rv = nghttp2_session_set_local_window_size(session_, NGHTTP2_FLAG_NONE, 0,
                                              window_size);
@@ -1726,9 +1725,9 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
   }
 
   auto nva = std::vector<nghttp2_nv>();
-  // 5 means :status and possible server, via, x-http2-push, and
-  // set-cookie (for affinity cookie) header field.
-  nva.reserve(resp.fs.headers().size() + 5 +
+  // 6 means :status and possible server, via, x-http2-push, alt-svc,
+  // and set-cookie (for affinity cookie) header field.
+  nva.reserve(resp.fs.headers().size() + 6 +
               httpconf.add_response_headers.size());
 
   if (downstream->get_non_final_response()) {
@@ -1796,6 +1795,14 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
     }
   }
 
+  if (!resp.fs.header(http2::HD_ALT_SVC)) {
+    // We won't change or alter alt-svc from backend for now
+    if (!httpconf.http2_altsvc_header_value.empty()) {
+      nva.push_back(http2::make_nv_ls_nocopy(
+          "alt-svc", httpconf.http2_altsvc_header_value));
+    }
+  }
+
   auto via = resp.fs.header(http2::HD_VIA);
   if (httpconf.no_via) {
     if (via) {
diff --git a/src/shrpx_http3_upstream.cc b/src/shrpx_http3_upstream.cc
new file mode 100644 (file)
index 0000000..956215c
--- /dev/null
@@ -0,0 +1,2737 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "shrpx_http3_upstream.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <netinet/udp.h>
+
+#include <cstdio>
+
+#include <ngtcp2/ngtcp2_crypto.h>
+
+#include "shrpx_client_handler.h"
+#include "shrpx_downstream.h"
+#include "shrpx_downstream_connection.h"
+#include "shrpx_log.h"
+#include "shrpx_quic.h"
+#include "shrpx_worker.h"
+#include "shrpx_http.h"
+#include "shrpx_connection_handler.h"
+#ifdef HAVE_MRUBY
+#  include "shrpx_mruby.h"
+#endif // HAVE_MRUBY
+#include "http3.h"
+#include "util.h"
+
+namespace shrpx {
+
+namespace {
+void idle_timeoutcb(struct ev_loop *loop, ev_timer *w, int revents) {
+  auto upstream = static_cast<Http3Upstream *>(w->data);
+
+  if (LOG_ENABLED(INFO)) {
+    ULOG(INFO, upstream) << "QUIC idle timeout";
+  }
+
+  upstream->idle_close();
+
+  auto handler = upstream->get_client_handler();
+
+  delete handler;
+}
+} // namespace
+
+namespace {
+void timeoutcb(struct ev_loop *loop, ev_timer *w, int revents) {
+  auto upstream = static_cast<Http3Upstream *>(w->data);
+
+  if (upstream->handle_expiry() != 0 || upstream->on_write() != 0) {
+    goto fail;
+  }
+
+  return;
+
+fail:
+  auto handler = upstream->get_client_handler();
+
+  delete handler;
+}
+} // namespace
+
+namespace {
+void shutdown_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
+  auto upstream = static_cast<Http3Upstream *>(w->data);
+  auto handler = upstream->get_client_handler();
+
+  if (upstream->submit_goaway() != 0) {
+    delete handler;
+  }
+}
+} // namespace
+
+namespace {
+void prepare_cb(struct ev_loop *loop, ev_prepare *w, int revent) {
+  auto upstream = static_cast<Http3Upstream *>(w->data);
+  auto handler = upstream->get_client_handler();
+
+  if (upstream->check_shutdown() != 0) {
+    delete handler;
+  }
+}
+} // namespace
+
+namespace {
+size_t downstream_queue_size(Worker *worker) {
+  auto &downstreamconf = *worker->get_downstream_config();
+
+  if (get_config()->http2_proxy) {
+    return downstreamconf.connections_per_host;
+  }
+
+  return downstreamconf.connections_per_frontend;
+}
+} // namespace
+
+Http3Upstream::Http3Upstream(ClientHandler *handler)
+    : handler_{handler},
+      max_udp_payload_size_{SHRPX_QUIC_MAX_UDP_PAYLOAD_SIZE},
+      qlog_fd_{-1},
+      hashed_scid_{},
+      conn_{nullptr},
+      tls_alert_{0},
+      httpconn_{nullptr},
+      downstream_queue_{downstream_queue_size(handler->get_worker()),
+                        !get_config()->http2_proxy},
+      idle_close_{false},
+      retry_close_{false} {
+  ev_timer_init(&timer_, timeoutcb, 0., 0.);
+  timer_.data = this;
+
+  auto config = get_config();
+  auto &quicconf = config->quic;
+
+  ev_timer_init(&idle_timer_, idle_timeoutcb, 0.,
+                quicconf.upstream.timeout.idle);
+  idle_timer_.data = this;
+
+  ev_timer_init(&shutdown_timer_, shutdown_timeout_cb, 0., 0.);
+  shutdown_timer_.data = this;
+
+  ev_prepare_init(&prep_, prepare_cb);
+  prep_.data = this;
+  ev_prepare_start(handler_->get_loop(), &prep_);
+}
+
+Http3Upstream::~Http3Upstream() {
+  auto loop = handler_->get_loop();
+
+  ev_prepare_stop(loop, &prep_);
+  ev_timer_stop(loop, &shutdown_timer_);
+  ev_timer_stop(loop, &idle_timer_);
+  ev_timer_stop(loop, &timer_);
+
+  nghttp3_conn_del(httpconn_);
+
+  ngtcp2_conn_del(conn_);
+
+  if (qlog_fd_ != -1) {
+    close(qlog_fd_);
+  }
+}
+
+namespace {
+void log_printf(void *user_data, const char *fmt, ...) {
+  va_list ap;
+  std::array<char, 4096> buf;
+
+  va_start(ap, fmt);
+  auto nwrite = vsnprintf(buf.data(), buf.size(), fmt, ap);
+  va_end(ap);
+
+  if (static_cast<size_t>(nwrite) >= buf.size()) {
+    nwrite = buf.size() - 1;
+  }
+
+  buf[nwrite++] = '\n';
+
+  while (write(fileno(stderr), buf.data(), nwrite) == -1 && errno == EINTR)
+    ;
+}
+} // namespace
+
+namespace {
+void qlog_write(void *user_data, uint32_t flags, const void *data,
+                size_t datalen) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  upstream->qlog_write(data, datalen, flags & NGTCP2_QLOG_WRITE_FLAG_FIN);
+}
+} // namespace
+
+void Http3Upstream::qlog_write(const void *data, size_t datalen, bool fin) {
+  assert(qlog_fd_ != -1);
+
+  ssize_t nwrite;
+
+  while ((nwrite = write(qlog_fd_, data, datalen)) == -1 && errno == EINTR)
+    ;
+
+  if (fin) {
+    close(qlog_fd_);
+    qlog_fd_ = -1;
+  }
+}
+
+namespace {
+void rand(uint8_t *dest, size_t destlen, const ngtcp2_rand_ctx *rand_ctx) {
+  util::random_bytes(dest, dest + destlen,
+                     *static_cast<std::mt19937 *>(rand_ctx->native_handle));
+}
+} // namespace
+
+namespace {
+int get_new_connection_id(ngtcp2_conn *conn, ngtcp2_cid *cid, uint8_t *token,
+                          size_t cidlen, void *user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+  auto handler = upstream->get_client_handler();
+  auto worker = handler->get_worker();
+  auto conn_handler = worker->get_connection_handler();
+  auto &qkms = conn_handler->get_quic_keying_materials();
+  auto &qkm = qkms->keying_materials.front();
+
+  if (generate_quic_connection_id(*cid, cidlen, worker->get_cid_prefix(),
+                                  qkm.id, qkm.cid_encryption_key.data()) != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  if (generate_quic_stateless_reset_token(token, *cid, qkm.secret.data(),
+                                          qkm.secret.size()) != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  auto quic_connection_handler = worker->get_quic_connection_handler();
+
+  quic_connection_handler->add_connection_id(*cid, handler);
+
+  return 0;
+}
+} // namespace
+
+namespace {
+int remove_connection_id(ngtcp2_conn *conn, const ngtcp2_cid *cid,
+                         void *user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+  auto handler = upstream->get_client_handler();
+  auto worker = handler->get_worker();
+  auto quic_conn_handler = worker->get_quic_connection_handler();
+
+  quic_conn_handler->remove_connection_id(*cid);
+
+  return 0;
+}
+} // namespace
+
+void Http3Upstream::http_begin_request_headers(int64_t stream_id) {
+  auto downstream =
+      std::make_unique<Downstream>(this, handler_->get_mcpool(), stream_id);
+  nghttp3_conn_set_stream_user_data(httpconn_, stream_id, downstream.get());
+
+  downstream->reset_upstream_rtimer();
+
+  handler_->repeat_read_timer();
+
+  auto &req = downstream->request();
+  req.http_major = 3;
+  req.http_minor = 0;
+
+  add_pending_downstream(std::move(downstream));
+}
+
+void Http3Upstream::add_pending_downstream(
+    std::unique_ptr<Downstream> downstream) {
+  downstream_queue_.add_pending(std::move(downstream));
+}
+
+namespace {
+int recv_stream_data(ngtcp2_conn *conn, uint32_t flags, int64_t stream_id,
+                     uint64_t offset, const uint8_t *data, size_t datalen,
+                     void *user_data, void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  if (upstream->recv_stream_data(flags, stream_id, data, datalen) != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::recv_stream_data(uint32_t flags, int64_t stream_id,
+                                    const uint8_t *data, size_t datalen) {
+  assert(httpconn_);
+
+  auto nconsumed = nghttp3_conn_read_stream(
+      httpconn_, stream_id, data, datalen, flags & NGTCP2_STREAM_DATA_FLAG_FIN);
+  if (nconsumed < 0) {
+    ULOG(ERROR, this) << "nghttp3_conn_read_stream: "
+                      << nghttp3_strerror(nconsumed);
+    last_error_ = quic::err_application(nconsumed);
+    return -1;
+  }
+
+  ngtcp2_conn_extend_max_stream_offset(conn_, stream_id, nconsumed);
+  ngtcp2_conn_extend_max_offset(conn_, nconsumed);
+
+  return 0;
+}
+
+namespace {
+int stream_close(ngtcp2_conn *conn, uint32_t flags, int64_t stream_id,
+                 uint64_t app_error_code, void *user_data,
+                 void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  if (!(flags & NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET)) {
+    app_error_code = NGHTTP3_H3_NO_ERROR;
+  }
+
+  if (upstream->stream_close(stream_id, app_error_code) != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::stream_close(int64_t stream_id, uint64_t app_error_code) {
+  if (!httpconn_) {
+    return 0;
+  }
+
+  auto rv = nghttp3_conn_close_stream(httpconn_, stream_id, app_error_code);
+  switch (rv) {
+  case 0:
+    break;
+  case NGHTTP3_ERR_STREAM_NOT_FOUND:
+    if (ngtcp2_is_bidi_stream(stream_id)) {
+      ngtcp2_conn_extend_max_streams_bidi(conn_, 1);
+    }
+    break;
+  default:
+    ULOG(ERROR, this) << "nghttp3_conn_close_stream: " << nghttp3_strerror(rv);
+    last_error_ = quic::err_application(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+namespace {
+int acked_stream_data_offset(ngtcp2_conn *conn, int64_t stream_id,
+                             uint64_t offset, uint64_t datalen, void *user_data,
+                             void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  if (upstream->acked_stream_data_offset(stream_id, datalen) != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::acked_stream_data_offset(int64_t stream_id,
+                                            uint64_t datalen) {
+  if (!httpconn_) {
+    return 0;
+  }
+
+  auto rv = nghttp3_conn_add_ack_offset(httpconn_, stream_id, datalen);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "nghttp3_conn_add_ack_offset: "
+                      << nghttp3_strerror(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+namespace {
+int extend_max_stream_data(ngtcp2_conn *conn, int64_t stream_id,
+                           uint64_t max_data, void *user_data,
+                           void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  if (upstream->extend_max_stream_data(stream_id) != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::extend_max_stream_data(int64_t stream_id) {
+  if (!httpconn_) {
+    return 0;
+  }
+
+  auto rv = nghttp3_conn_unblock_stream(httpconn_, stream_id);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "nghttp3_conn_unblock_stream: "
+                      << nghttp3_strerror(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+namespace {
+int extend_max_remote_streams_bidi(ngtcp2_conn *conn, uint64_t max_streams,
+                                   void *user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  upstream->extend_max_remote_streams_bidi(max_streams);
+
+  return 0;
+}
+} // namespace
+
+void Http3Upstream::extend_max_remote_streams_bidi(uint64_t max_streams) {
+  nghttp3_conn_set_max_client_streams_bidi(httpconn_, max_streams);
+}
+
+namespace {
+int stream_reset(ngtcp2_conn *conn, int64_t stream_id, uint64_t final_size,
+                 uint64_t app_error_code, void *user_data,
+                 void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  if (upstream->http_shutdown_stream_read(stream_id) != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::http_shutdown_stream_read(int64_t stream_id) {
+  if (!httpconn_) {
+    return 0;
+  }
+
+  auto rv = nghttp3_conn_shutdown_stream_read(httpconn_, stream_id);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "nghttp3_conn_shutdown_stream_read: "
+                      << nghttp3_strerror(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+namespace {
+int stream_stop_sending(ngtcp2_conn *conn, int64_t stream_id,
+                        uint64_t app_error_code, void *user_data,
+                        void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  if (upstream->http_shutdown_stream_read(stream_id) != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+namespace {
+int handshake_completed(ngtcp2_conn *conn, void *user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  if (upstream->handshake_completed() != 0) {
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::handshake_completed() {
+  handler_->set_alpn_from_conn();
+
+  auto alpn = handler_->get_alpn();
+  if (alpn.empty()) {
+    ULOG(ERROR, this) << "NO ALPN was negotiated";
+    return -1;
+  }
+
+  std::array<uint8_t, NGTCP2_CRYPTO_MAX_REGULAR_TOKENLEN> token;
+  size_t tokenlen;
+
+  auto path = ngtcp2_conn_get_path(conn_);
+  auto worker = handler_->get_worker();
+  auto conn_handler = worker->get_connection_handler();
+  auto &qkms = conn_handler->get_quic_keying_materials();
+  auto &qkm = qkms->keying_materials.front();
+
+  if (generate_token(token.data(), tokenlen, path->remote.addr,
+                     path->remote.addrlen, qkm.secret.data(),
+                     qkm.secret.size()) != 0) {
+    return 0;
+  }
+
+  auto rv = ngtcp2_conn_submit_new_token(conn_, token.data(), tokenlen);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "ngtcp2_conn_submit_new_token: "
+                      << ngtcp2_strerror(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+int Http3Upstream::init(const UpstreamAddr *faddr, const Address &remote_addr,
+                        const Address &local_addr,
+                        const ngtcp2_pkt_hd &initial_hd,
+                        const ngtcp2_cid *odcid, const uint8_t *token,
+                        size_t tokenlen) {
+  int rv;
+
+  auto worker = handler_->get_worker();
+  auto conn_handler = worker->get_connection_handler();
+
+  auto callbacks = ngtcp2_callbacks{
+      nullptr, // client_initial
+      ngtcp2_crypto_recv_client_initial_cb,
+      ngtcp2_crypto_recv_crypto_data_cb,
+      shrpx::handshake_completed,
+      nullptr, // recv_version_negotiation
+      ngtcp2_crypto_encrypt_cb,
+      ngtcp2_crypto_decrypt_cb,
+      ngtcp2_crypto_hp_mask_cb,
+      shrpx::recv_stream_data,
+      shrpx::acked_stream_data_offset,
+      nullptr, // stream_open
+      shrpx::stream_close,
+      nullptr, // recv_stateless_reset
+      nullptr, // recv_retry
+      nullptr, // extend_max_local_streams_bidi
+      nullptr, // extend_max_local_streams_uni
+      rand,
+      get_new_connection_id,
+      remove_connection_id,
+      ngtcp2_crypto_update_key_cb,
+      nullptr, // path_validation
+      nullptr, // select_preferred_addr
+      shrpx::stream_reset,
+      shrpx::extend_max_remote_streams_bidi,
+      nullptr, // extend_max_remote_streams_uni
+      shrpx::extend_max_stream_data,
+      nullptr, // dcid_status
+      nullptr, // handshake_confirmed
+      nullptr, // recv_new_token
+      ngtcp2_crypto_delete_crypto_aead_ctx_cb,
+      ngtcp2_crypto_delete_crypto_cipher_ctx_cb,
+      nullptr, // recv_datagram
+      nullptr, // ack_datagram
+      nullptr, // lost_datagram
+      ngtcp2_crypto_get_path_challenge_data_cb,
+      shrpx::stream_stop_sending,
+  };
+
+  auto config = get_config();
+  auto &quicconf = config->quic;
+  auto &http3conf = config->http3;
+
+  auto &qkms = conn_handler->get_quic_keying_materials();
+  auto &qkm = qkms->keying_materials.front();
+
+  ngtcp2_cid scid;
+
+  if (generate_quic_connection_id(scid, SHRPX_QUIC_SCIDLEN,
+                                  worker->get_cid_prefix(), qkm.id,
+                                  qkm.cid_encryption_key.data()) != 0) {
+    return -1;
+  }
+
+  ngtcp2_settings settings;
+  ngtcp2_settings_default(&settings);
+  if (quicconf.upstream.debug.log) {
+    settings.log_printf = log_printf;
+  }
+
+  if (!quicconf.upstream.qlog.dir.empty()) {
+    auto fd = open_qlog_file(quicconf.upstream.qlog.dir, scid);
+    if (fd != -1) {
+      qlog_fd_ = fd;
+      settings.qlog.odcid = initial_hd.dcid;
+      settings.qlog.write = shrpx::qlog_write;
+    }
+  }
+
+  settings.initial_ts = quic_timestamp();
+  settings.initial_rtt = static_cast<ngtcp2_tstamp>(
+      quicconf.upstream.initial_rtt * NGTCP2_SECONDS);
+  settings.cc_algo = quicconf.upstream.congestion_controller;
+  settings.max_window = http3conf.upstream.max_connection_window_size;
+  settings.max_stream_window = http3conf.upstream.max_window_size;
+  settings.max_udp_payload_size = SHRPX_QUIC_MAX_UDP_PAYLOAD_SIZE;
+  settings.assume_symmetric_path = 1;
+  settings.rand_ctx.native_handle = &worker->get_randgen();
+  settings.token = ngtcp2_vec{const_cast<uint8_t *>(token), tokenlen};
+
+  ngtcp2_transport_params params;
+  ngtcp2_transport_params_default(&params);
+  params.initial_max_streams_bidi = http3conf.upstream.max_concurrent_streams;
+  // The minimum number of unidirectional streams required for HTTP/3.
+  params.initial_max_streams_uni = 3;
+  params.initial_max_data = http3conf.upstream.connection_window_size;
+  params.initial_max_stream_data_bidi_remote = http3conf.upstream.window_size;
+  params.initial_max_stream_data_uni = http3conf.upstream.window_size;
+  params.max_idle_timeout = static_cast<ngtcp2_tstamp>(
+      quicconf.upstream.timeout.idle * NGTCP2_SECONDS);
+
+#ifdef OPENSSL_IS_BORINGSSL
+  if (quicconf.upstream.early_data) {
+    ngtcp2_transport_params early_data_params{
+        .initial_max_stream_data_bidi_local =
+            params.initial_max_stream_data_bidi_local,
+        .initial_max_stream_data_bidi_remote =
+            params.initial_max_stream_data_bidi_remote,
+        .initial_max_stream_data_uni = params.initial_max_stream_data_uni,
+        .initial_max_data = params.initial_max_data,
+        .initial_max_streams_bidi = params.initial_max_streams_bidi,
+        .initial_max_streams_uni = params.initial_max_streams_uni,
+    };
+
+    // TODO include HTTP/3 SETTINGS
+
+    std::array<uint8_t, 128> quic_early_data_ctx;
+
+    auto quic_early_data_ctxlen = ngtcp2_encode_transport_params(
+        quic_early_data_ctx.data(), quic_early_data_ctx.size(),
+        NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS, &early_data_params);
+
+    assert(quic_early_data_ctxlen > 0);
+    assert(static_cast<size_t>(quic_early_data_ctxlen) <=
+           quic_early_data_ctx.size());
+
+    if (SSL_set_quic_early_data_context(handler_->get_ssl(),
+                                        quic_early_data_ctx.data(),
+                                        quic_early_data_ctxlen) != 1) {
+      ULOG(ERROR, this) << "SSL_set_quic_early_data_context failed";
+      return -1;
+    }
+  }
+#endif // OPENSSL_IS_BORINGSSL
+
+  if (odcid) {
+    params.original_dcid = *odcid;
+    params.retry_scid = initial_hd.dcid;
+    params.retry_scid_present = 1;
+  } else {
+    params.original_dcid = initial_hd.dcid;
+  }
+
+  rv = generate_quic_stateless_reset_token(
+      params.stateless_reset_token, scid, qkm.secret.data(), qkm.secret.size());
+  if (rv != 0) {
+    ULOG(ERROR, this) << "generate_quic_stateless_reset_token failed";
+    return -1;
+  }
+  params.stateless_reset_token_present = 1;
+
+  auto path = ngtcp2_path{
+      {local_addr.len, const_cast<sockaddr *>(&local_addr.su.sa)},
+      {remote_addr.len, const_cast<sockaddr *>(&remote_addr.su.sa)},
+      const_cast<UpstreamAddr *>(faddr),
+  };
+
+  rv = ngtcp2_conn_server_new(&conn_, &initial_hd.scid, &scid, &path,
+                              initial_hd.version, &callbacks, &settings,
+                              &params, nullptr, this);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "ngtcp2_conn_server_new: " << ngtcp2_strerror(rv);
+    return -1;
+  }
+
+  ngtcp2_conn_set_tls_native_handle(conn_, handler_->get_ssl());
+
+  auto quic_connection_handler = worker->get_quic_connection_handler();
+
+  if (generate_quic_hashed_connection_id(hashed_scid_, remote_addr, local_addr,
+                                         initial_hd.dcid) != 0) {
+    return -1;
+  }
+
+  quic_connection_handler->add_connection_id(hashed_scid_, handler_);
+  quic_connection_handler->add_connection_id(scid, handler_);
+
+  return 0;
+}
+
+int Http3Upstream::on_read() { return 0; }
+
+int Http3Upstream::on_write() {
+  if (write_streams() != 0) {
+    return -1;
+  }
+
+  reset_timer();
+
+  return 0;
+}
+
+int Http3Upstream::write_streams() {
+  std::array<nghttp3_vec, 16> vec;
+  std::array<uint8_t, 64_k> buf;
+  auto max_udp_payload_size = std::min(
+      max_udp_payload_size_, ngtcp2_conn_get_path_max_udp_payload_size(conn_));
+  size_t max_pktcnt =
+      std::min(static_cast<size_t>(64_k), ngtcp2_conn_get_send_quantum(conn_)) /
+      max_udp_payload_size;
+  ngtcp2_pkt_info pi;
+  uint8_t *bufpos = buf.data();
+  ngtcp2_path_storage ps, prev_ps;
+  size_t pktcnt = 0;
+  int rv;
+  auto ts = quic_timestamp();
+
+  ngtcp2_path_storage_zero(&ps);
+  ngtcp2_path_storage_zero(&prev_ps);
+
+  auto config = get_config();
+  auto &quicconf = config->quic;
+
+  if (quicconf.upstream.congestion_controller != NGTCP2_CC_ALGO_BBR) {
+    max_pktcnt = std::min(max_pktcnt, static_cast<size_t>(10));
+  }
+
+  for (;;) {
+    int64_t stream_id = -1;
+    int fin = 0;
+    nghttp3_ssize sveccnt = 0;
+
+    if (httpconn_ && ngtcp2_conn_get_max_data_left(conn_)) {
+      sveccnt = nghttp3_conn_writev_stream(httpconn_, &stream_id, &fin,
+                                           vec.data(), vec.size());
+      if (sveccnt < 0) {
+        ULOG(ERROR, this) << "nghttp3_conn_writev_stream: "
+                          << nghttp3_strerror(sveccnt);
+        last_error_ = quic::err_application(sveccnt);
+        return handle_error();
+      }
+    }
+
+    ngtcp2_ssize ndatalen;
+    auto v = vec.data();
+    auto vcnt = static_cast<size_t>(sveccnt);
+
+    uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_MORE;
+    if (fin) {
+      flags |= NGTCP2_WRITE_STREAM_FLAG_FIN;
+    }
+
+    auto nwrite = ngtcp2_conn_writev_stream(
+        conn_, &ps.path, &pi, bufpos, max_udp_payload_size, &ndatalen, flags,
+        stream_id, reinterpret_cast<const ngtcp2_vec *>(v), vcnt, ts);
+    if (nwrite < 0) {
+      switch (nwrite) {
+      case NGTCP2_ERR_STREAM_DATA_BLOCKED:
+        assert(ndatalen == -1);
+        rv = nghttp3_conn_block_stream(httpconn_, stream_id);
+        if (rv != 0) {
+          ULOG(ERROR, this)
+              << "nghttp3_conn_block_stream: " << nghttp3_strerror(rv);
+          last_error_ = quic::err_application(rv);
+          return handle_error();
+        }
+        continue;
+      case NGTCP2_ERR_STREAM_SHUT_WR:
+        assert(ndatalen == -1);
+        rv = nghttp3_conn_shutdown_stream_write(httpconn_, stream_id);
+        if (rv != 0) {
+          ULOG(ERROR, this)
+              << "nghttp3_conn_shutdown_stream_write: " << nghttp3_strerror(rv);
+          last_error_ = quic::err_application(rv);
+          return handle_error();
+        }
+        continue;
+      case NGTCP2_ERR_WRITE_MORE:
+        assert(ndatalen >= 0);
+        rv = nghttp3_conn_add_write_offset(httpconn_, stream_id, ndatalen);
+        if (rv != 0) {
+          ULOG(ERROR, this)
+              << "nghttp3_conn_add_write_offset: " << nghttp3_strerror(rv);
+          last_error_ = quic::err_application(rv);
+          return handle_error();
+        }
+        continue;
+      }
+
+      assert(ndatalen == -1);
+
+      ULOG(ERROR, this) << "ngtcp2_conn_writev_stream: "
+                        << ngtcp2_strerror(nwrite);
+
+      last_error_ = quic::err_transport(nwrite);
+
+      handler_->get_connection()->wlimit.stopw();
+
+      return handle_error();
+    } else if (ndatalen >= 0) {
+      rv = nghttp3_conn_add_write_offset(httpconn_, stream_id, ndatalen);
+      if (rv != 0) {
+        ULOG(ERROR, this) << "nghttp3_conn_add_write_offset: "
+                          << nghttp3_strerror(rv);
+        last_error_ = quic::err_application(rv);
+        return handle_error();
+      }
+    }
+
+    if (nwrite == 0) {
+      if (bufpos - buf.data()) {
+        send_packet(static_cast<UpstreamAddr *>(prev_ps.path.user_data),
+                    prev_ps.path.remote.addr, prev_ps.path.remote.addrlen,
+                    prev_ps.path.local.addr, prev_ps.path.local.addrlen,
+                    buf.data(), bufpos - buf.data(), max_udp_payload_size);
+
+        reset_idle_timer();
+      }
+
+      ngtcp2_conn_update_pkt_tx_time(conn_, ts);
+
+      handler_->get_connection()->wlimit.stopw();
+
+      return 0;
+    }
+
+    bufpos += nwrite;
+
+#ifdef UDP_SEGMENT
+    if (pktcnt == 0) {
+      ngtcp2_path_copy(&prev_ps.path, &ps.path);
+    } else if (!ngtcp2_path_eq(&prev_ps.path, &ps.path)) {
+      send_packet(static_cast<UpstreamAddr *>(prev_ps.path.user_data),
+                  prev_ps.path.remote.addr, prev_ps.path.remote.addrlen,
+                  prev_ps.path.local.addr, prev_ps.path.local.addrlen,
+                  buf.data(), bufpos - buf.data() - nwrite,
+                  max_udp_payload_size);
+
+      send_packet(static_cast<UpstreamAddr *>(ps.path.user_data),
+                  ps.path.remote.addr, ps.path.remote.addrlen,
+                  ps.path.local.addr, ps.path.local.addrlen, bufpos - nwrite,
+                  nwrite, max_udp_payload_size);
+
+      ngtcp2_conn_update_pkt_tx_time(conn_, ts);
+      reset_idle_timer();
+
+      handler_->signal_write();
+
+      return 0;
+    }
+
+    if (++pktcnt == max_pktcnt ||
+        static_cast<size_t>(nwrite) < max_udp_payload_size) {
+      send_packet(static_cast<UpstreamAddr *>(ps.path.user_data),
+                  ps.path.remote.addr, ps.path.remote.addrlen,
+                  ps.path.local.addr, ps.path.local.addrlen, buf.data(),
+                  bufpos - buf.data(), max_udp_payload_size);
+
+      ngtcp2_conn_update_pkt_tx_time(conn_, ts);
+      reset_idle_timer();
+
+      handler_->signal_write();
+
+      return 0;
+    }
+#else  // !UDP_SEGMENT
+    send_packet(static_cast<UpstreamAddr *>(ps.path.user_data),
+                ps.path.remote.addr, ps.path.remote.addrlen, ps.path.local.addr,
+                ps.path.local.addrlen, buf.data(), bufpos - buf.data(), 0);
+
+    if (++pktcnt == max_pktcnt) {
+      ngtcp2_conn_update_pkt_tx_time(conn_, ts);
+      reset_idle_timer();
+
+      handler_->signal_write();
+
+      return 0;
+    }
+
+    bufpos = buf.data();
+#endif // !UDP_SEGMENT
+  }
+
+  return 0;
+}
+
+int Http3Upstream::on_timeout(Downstream *downstream) { return 0; }
+
+int Http3Upstream::on_downstream_abort_request(Downstream *downstream,
+                                               unsigned int status_code) {
+  int rv;
+
+  rv = error_reply(downstream, status_code);
+
+  if (rv != 0) {
+    return -1;
+  }
+
+  handler_->signal_write();
+
+  return 0;
+}
+
+int Http3Upstream::on_downstream_abort_request_with_https_redirect(
+    Downstream *downstream) {
+  int rv;
+
+  rv = redirect_to_https(downstream);
+  if (rv != 0) {
+    return -1;
+  }
+
+  handler_->signal_write();
+  return 0;
+}
+
+namespace {
+uint64_t
+infer_upstream_shutdown_stream_error_code(uint32_t downstream_error_code) {
+  // NGHTTP2_REFUSED_STREAM is important because it tells upstream
+  // client to retry.
+  switch (downstream_error_code) {
+  case NGHTTP2_NO_ERROR:
+    return NGHTTP3_H3_NO_ERROR;
+  case NGHTTP2_REFUSED_STREAM:
+    return NGHTTP3_H3_REQUEST_REJECTED;
+  default:
+    return NGHTTP3_H3_INTERNAL_ERROR;
+  }
+}
+} // namespace
+
+int Http3Upstream::downstream_read(DownstreamConnection *dconn) {
+  auto downstream = dconn->get_downstream();
+
+  if (downstream->get_response_state() == DownstreamState::MSG_RESET) {
+    // The downstream stream was reset (canceled). In this case,
+    // RST_STREAM to the upstream and delete downstream connection
+    // here. Deleting downstream will be taken place at
+    // on_stream_close_callback.
+    shutdown_stream(downstream,
+                    infer_upstream_shutdown_stream_error_code(
+                        downstream->get_response_rst_stream_error_code()));
+    downstream->pop_downstream_connection();
+    // dconn was deleted
+    dconn = nullptr;
+  } else if (downstream->get_response_state() ==
+             DownstreamState::MSG_BAD_HEADER) {
+    if (error_reply(downstream, 502) != 0) {
+      return -1;
+    }
+    downstream->pop_downstream_connection();
+    // dconn was deleted
+    dconn = nullptr;
+  } else {
+    auto rv = downstream->on_read();
+    if (rv == SHRPX_ERR_EOF) {
+      if (downstream->get_request_header_sent()) {
+        return downstream_eof(dconn);
+      }
+      return SHRPX_ERR_RETRY;
+    }
+    if (rv == SHRPX_ERR_DCONN_CANCELED) {
+      downstream->pop_downstream_connection();
+      handler_->signal_write();
+      return 0;
+    }
+    if (rv != 0) {
+      if (rv != SHRPX_ERR_NETWORK) {
+        if (LOG_ENABLED(INFO)) {
+          DCLOG(INFO, dconn) << "HTTP parser failure";
+        }
+      }
+      return downstream_error(dconn, Downstream::EVENT_ERROR);
+    }
+
+    if (downstream->can_detach_downstream_connection()) {
+      // Keep-alive
+      downstream->detach_downstream_connection();
+    }
+  }
+
+  handler_->signal_write();
+
+  // At this point, downstream may be deleted.
+
+  return 0;
+}
+
+int Http3Upstream::downstream_write(DownstreamConnection *dconn) {
+  int rv;
+  rv = dconn->on_write();
+  if (rv == SHRPX_ERR_NETWORK) {
+    return downstream_error(dconn, Downstream::EVENT_ERROR);
+  }
+  if (rv != 0) {
+    return rv;
+  }
+  return 0;
+}
+
+int Http3Upstream::downstream_eof(DownstreamConnection *dconn) {
+  auto downstream = dconn->get_downstream();
+
+  if (LOG_ENABLED(INFO)) {
+    DCLOG(INFO, dconn) << "EOF. stream_id=" << downstream->get_stream_id();
+  }
+
+  // Delete downstream connection. If we don't delete it here, it will
+  // be pooled in on_stream_close_callback.
+  downstream->pop_downstream_connection();
+  // dconn was deleted
+  dconn = nullptr;
+  // downstream wil be deleted in on_stream_close_callback.
+  if (downstream->get_response_state() == DownstreamState::HEADER_COMPLETE) {
+    // Server may indicate the end of the request by EOF
+    if (LOG_ENABLED(INFO)) {
+      ULOG(INFO, this) << "Downstream body was ended by EOF";
+    }
+    downstream->set_response_state(DownstreamState::MSG_COMPLETE);
+
+    // For tunneled connection, MSG_COMPLETE signals
+    // downstream_read_data_callback to send RST_STREAM after pending
+    // response body is sent. This is needed to ensure that RST_STREAM
+    // is sent after all pending data are sent.
+    on_downstream_body_complete(downstream);
+  } else if (downstream->get_response_state() !=
+             DownstreamState::MSG_COMPLETE) {
+    // If stream was not closed, then we set MSG_COMPLETE and let
+    // on_stream_close_callback delete downstream.
+    if (error_reply(downstream, 502) != 0) {
+      return -1;
+    }
+  }
+  handler_->signal_write();
+  // At this point, downstream may be deleted.
+  return 0;
+}
+
+int Http3Upstream::downstream_error(DownstreamConnection *dconn, int events) {
+  auto downstream = dconn->get_downstream();
+
+  if (LOG_ENABLED(INFO)) {
+    if (events & Downstream::EVENT_ERROR) {
+      DCLOG(INFO, dconn) << "Downstream network/general error";
+    } else {
+      DCLOG(INFO, dconn) << "Timeout";
+    }
+    if (downstream->get_upgraded()) {
+      DCLOG(INFO, dconn) << "Note: this is tunnel connection";
+    }
+  }
+
+  // Delete downstream connection. If we don't delete it here, it will
+  // be pooled in on_stream_close_callback.
+  downstream->pop_downstream_connection();
+  // dconn was deleted
+  dconn = nullptr;
+
+  if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
+    // For SSL tunneling, we issue RST_STREAM. For other types of
+    // stream, we don't have to do anything since response was
+    // complete.
+    if (downstream->get_upgraded()) {
+      shutdown_stream(downstream, NGHTTP3_H3_NO_ERROR);
+    }
+  } else {
+    if (downstream->get_response_state() == DownstreamState::HEADER_COMPLETE) {
+      if (downstream->get_upgraded()) {
+        on_downstream_body_complete(downstream);
+      } else {
+        shutdown_stream(downstream, NGHTTP3_H3_INTERNAL_ERROR);
+      }
+    } else {
+      unsigned int status;
+      if (events & Downstream::EVENT_TIMEOUT) {
+        if (downstream->get_request_header_sent()) {
+          status = 504;
+        } else {
+          status = 408;
+        }
+      } else {
+        status = 502;
+      }
+      if (error_reply(downstream, status) != 0) {
+        return -1;
+      }
+    }
+    downstream->set_response_state(DownstreamState::MSG_COMPLETE);
+  }
+  handler_->signal_write();
+  // At this point, downstream may be deleted.
+  return 0;
+}
+
+ClientHandler *Http3Upstream::get_client_handler() const { return handler_; }
+
+namespace {
+nghttp3_ssize downstream_read_data_callback(nghttp3_conn *conn,
+                                            int64_t stream_id, nghttp3_vec *vec,
+                                            size_t veccnt, uint32_t *pflags,
+                                            void *conn_user_data,
+                                            void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(conn_user_data);
+  auto downstream = static_cast<Downstream *>(stream_user_data);
+
+  assert(downstream);
+
+  auto body = downstream->get_response_buf();
+
+  assert(body);
+
+  if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
+    *pflags |= NGHTTP3_DATA_FLAG_EOF;
+  } else if (body->rleft_mark() == 0) {
+    downstream->disable_upstream_wtimer();
+    return NGHTTP3_ERR_WOULDBLOCK;
+  }
+
+  downstream->reset_upstream_wtimer();
+
+  veccnt = body->riovec_mark(reinterpret_cast<struct iovec *>(vec), veccnt);
+
+  assert((*pflags & NGHTTP3_DATA_FLAG_EOF) || veccnt);
+
+  downstream->response_sent_body_length += nghttp3_vec_len(vec, veccnt);
+
+  if ((*pflags & NGHTTP3_DATA_FLAG_EOF) &&
+      upstream->shutdown_stream_read(stream_id, NGHTTP3_H3_NO_ERROR) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+
+  return veccnt;
+}
+} // namespace
+
+int Http3Upstream::on_downstream_header_complete(Downstream *downstream) {
+  int rv;
+
+  const auto &req = downstream->request();
+  auto &resp = downstream->response();
+
+  auto &balloc = downstream->get_block_allocator();
+
+  if (LOG_ENABLED(INFO)) {
+    if (downstream->get_non_final_response()) {
+      DLOG(INFO, downstream) << "HTTP non-final response header";
+    } else {
+      DLOG(INFO, downstream) << "HTTP response header completed";
+    }
+  }
+
+  auto config = get_config();
+  auto &httpconf = config->http;
+
+  if (!config->http2_proxy && !httpconf.no_location_rewrite) {
+    downstream->rewrite_location_response_header(req.scheme);
+  }
+
+#ifdef HAVE_MRUBY
+  if (!downstream->get_non_final_response()) {
+    auto dconn = downstream->get_downstream_connection();
+    const auto &group = dconn->get_downstream_addr_group();
+    if (group) {
+      const auto &dmruby_ctx = group->shared_addr->mruby_ctx;
+
+      if (dmruby_ctx->run_on_response_proc(downstream) != 0) {
+        if (error_reply(downstream, 500) != 0) {
+          return -1;
+        }
+        // Returning -1 will signal deletion of dconn.
+        return -1;
+      }
+
+      if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
+        return -1;
+      }
+    }
+
+    auto worker = handler_->get_worker();
+    auto mruby_ctx = worker->get_mruby_context();
+
+    if (mruby_ctx->run_on_response_proc(downstream) != 0) {
+      if (error_reply(downstream, 500) != 0) {
+        return -1;
+      }
+      // Returning -1 will signal deletion of dconn.
+      return -1;
+    }
+
+    if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
+      return -1;
+    }
+  }
+#endif // HAVE_MRUBY
+
+  auto nva = std::vector<nghttp3_nv>();
+  // 4 means :status and possible server, via, and set-cookie (for
+  // affinity cookie) header field.
+  nva.reserve(resp.fs.headers().size() + 4 +
+              httpconf.add_response_headers.size());
+
+  if (downstream->get_non_final_response()) {
+    auto response_status = http2::stringify_status(balloc, resp.http_status);
+
+    nva.push_back(http3::make_nv_ls_nocopy(":status", response_status));
+
+    http3::copy_headers_to_nva_nocopy(nva, resp.fs.headers(),
+                                      http2::HDOP_STRIP_ALL);
+
+    if (LOG_ENABLED(INFO)) {
+      log_response_headers(downstream, nva);
+    }
+
+    rv = nghttp3_conn_submit_info(httpconn_, downstream->get_stream_id(),
+                                  nva.data(), nva.size());
+
+    resp.fs.clear_headers();
+
+    if (rv != 0) {
+      ULOG(FATAL, this) << "nghttp3_conn_submit_info() failed";
+      return -1;
+    }
+
+    return 0;
+  }
+
+  auto striphd_flags = http2::HDOP_STRIP_ALL & ~http2::HDOP_STRIP_VIA;
+  StringRef response_status;
+
+  if (req.connect_proto == ConnectProto::WEBSOCKET && resp.http_status == 101) {
+    response_status = http2::stringify_status(balloc, 200);
+    striphd_flags |= http2::HDOP_STRIP_SEC_WEBSOCKET_ACCEPT;
+  } else {
+    response_status = http2::stringify_status(balloc, resp.http_status);
+  }
+
+  nva.push_back(http3::make_nv_ls_nocopy(":status", response_status));
+
+  http3::copy_headers_to_nva_nocopy(nva, resp.fs.headers(), striphd_flags);
+
+  if (!config->http2_proxy && !httpconf.no_server_rewrite) {
+    nva.push_back(http3::make_nv_ls_nocopy("server", httpconf.server_name));
+  } else {
+    auto server = resp.fs.header(http2::HD_SERVER);
+    if (server) {
+      nva.push_back(http3::make_nv_ls_nocopy("server", (*server).value));
+    }
+  }
+
+  if (!req.regular_connect_method() || !downstream->get_upgraded()) {
+    auto affinity_cookie = downstream->get_affinity_cookie_to_send();
+    if (affinity_cookie) {
+      auto dconn = downstream->get_downstream_connection();
+      assert(dconn);
+      auto &group = dconn->get_downstream_addr_group();
+      auto &shared_addr = group->shared_addr;
+      auto &cookieconf = shared_addr->affinity.cookie;
+      auto secure =
+          http::require_cookie_secure_attribute(cookieconf.secure, req.scheme);
+      auto cookie_str = http::create_affinity_cookie(
+          balloc, cookieconf.name, affinity_cookie, cookieconf.path, secure);
+      nva.push_back(http3::make_nv_ls_nocopy("set-cookie", cookie_str));
+    }
+  }
+
+  auto via = resp.fs.header(http2::HD_VIA);
+  if (httpconf.no_via) {
+    if (via) {
+      nva.push_back(http3::make_nv_ls_nocopy("via", (*via).value));
+    }
+  } else {
+    // we don't create more than 16 bytes in
+    // http::create_via_header_value.
+    size_t len = 16;
+    if (via) {
+      len += via->value.size() + 2;
+    }
+
+    auto iov = make_byte_ref(balloc, len + 1);
+    auto p = iov.base;
+    if (via) {
+      p = std::copy(std::begin(via->value), std::end(via->value), p);
+      p = util::copy_lit(p, ", ");
+    }
+    p = http::create_via_header_value(p, resp.http_major, resp.http_minor);
+    *p = '\0';
+
+    nva.push_back(http3::make_nv_ls_nocopy("via", StringRef{iov.base, p}));
+  }
+
+  for (auto &p : httpconf.add_response_headers) {
+    nva.push_back(http3::make_nv_nocopy(p.name, p.value));
+  }
+
+  if (LOG_ENABLED(INFO)) {
+    log_response_headers(downstream, nva);
+  }
+
+  nghttp3_data_reader data_read;
+  data_read.read_data = downstream_read_data_callback;
+
+  nghttp3_data_reader *data_readptr;
+
+  if (downstream->expect_response_body() ||
+      downstream->expect_response_trailer()) {
+    data_readptr = &data_read;
+  } else {
+    data_readptr = nullptr;
+  }
+
+  rv = nghttp3_conn_submit_response(httpconn_, downstream->get_stream_id(),
+                                    nva.data(), nva.size(), data_readptr);
+  if (rv != 0) {
+    ULOG(FATAL, this) << "nghttp3_conn_submit_response() failed";
+    return -1;
+  }
+
+  if (data_readptr) {
+    downstream->reset_upstream_wtimer();
+  } else if (shutdown_stream_read(downstream->get_stream_id(),
+                                  NGHTTP3_H3_NO_ERROR) != 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int Http3Upstream::on_downstream_body(Downstream *downstream,
+                                      const uint8_t *data, size_t len,
+                                      bool flush) {
+  auto body = downstream->get_response_buf();
+  body->append(data, len);
+
+  if (flush) {
+    nghttp3_conn_resume_stream(httpconn_, downstream->get_stream_id());
+
+    downstream->ensure_upstream_wtimer();
+  }
+
+  return 0;
+}
+
+int Http3Upstream::on_downstream_body_complete(Downstream *downstream) {
+  if (LOG_ENABLED(INFO)) {
+    DLOG(INFO, downstream) << "HTTP response completed";
+  }
+
+  auto &resp = downstream->response();
+
+  if (!downstream->validate_response_recv_body_length()) {
+    shutdown_stream(downstream, NGHTTP3_H3_GENERAL_PROTOCOL_ERROR);
+    resp.connection_close = true;
+    return 0;
+  }
+
+  nghttp3_conn_resume_stream(httpconn_, downstream->get_stream_id());
+  downstream->ensure_upstream_wtimer();
+
+  return 0;
+}
+
+void Http3Upstream::on_handler_delete() {
+  for (auto d = downstream_queue_.get_downstreams(); d; d = d->dlnext) {
+    if (d->get_dispatch_state() == DispatchState::ACTIVE &&
+        d->accesslog_ready()) {
+      handler_->write_accesslog(d);
+    }
+  }
+
+  auto worker = handler_->get_worker();
+  auto quic_conn_handler = worker->get_quic_connection_handler();
+
+  std::vector<ngtcp2_cid> scids(ngtcp2_conn_get_num_scid(conn_) + 1);
+  ngtcp2_conn_get_scid(conn_, scids.data());
+  scids.back() = hashed_scid_;
+
+  for (auto &cid : scids) {
+    quic_conn_handler->remove_connection_id(cid);
+  }
+
+  if (idle_close_ || retry_close_) {
+    return;
+  }
+
+  // If this is not idle close, send CONNECTION_CLOSE.
+  if (!ngtcp2_conn_is_in_closing_period(conn_) &&
+      !ngtcp2_conn_is_in_draining_period(conn_)) {
+    ngtcp2_path_storage ps;
+    ngtcp2_pkt_info pi;
+    conn_close_.resize(SHRPX_QUIC_CONN_CLOSE_PKTLEN);
+
+    ngtcp2_path_storage_zero(&ps);
+
+    auto nwrite = ngtcp2_conn_write_connection_close(
+        conn_, &ps.path, &pi, conn_close_.data(), conn_close_.size(),
+        NGTCP2_NO_ERROR, quic_timestamp());
+    if (nwrite < 0) {
+      if (nwrite != NGTCP2_ERR_INVALID_STATE) {
+        ULOG(ERROR, this) << "ngtcp2_conn_write_connection_close: "
+                          << ngtcp2_strerror(nwrite);
+      }
+
+      return;
+    }
+
+    conn_close_.resize(nwrite);
+
+    send_packet(static_cast<UpstreamAddr *>(ps.path.user_data),
+                ps.path.remote.addr, ps.path.remote.addrlen, ps.path.local.addr,
+                ps.path.local.addrlen, conn_close_.data(), nwrite, 0);
+  }
+
+  auto d =
+      static_cast<ev_tstamp>(ngtcp2_conn_get_pto(conn_) * 3) / NGTCP2_SECONDS;
+
+  if (LOG_ENABLED(INFO)) {
+    ULOG(INFO, this) << "Enter close-wait period " << d << "s with "
+                     << conn_close_.size() << " bytes sentinel packet";
+  }
+
+  auto cw = std::make_unique<CloseWait>(worker, std::move(scids),
+                                        std::move(conn_close_), d);
+
+  quic_conn_handler->add_close_wait(cw.get());
+
+  cw.release();
+}
+
+int Http3Upstream::on_downstream_reset(Downstream *downstream, bool no_retry) {
+  int rv;
+
+  if (downstream->get_dispatch_state() != DispatchState::ACTIVE) {
+    // This is error condition when we failed push_request_headers()
+    // in initiate_downstream().  Otherwise, we have
+    // DispatchState::ACTIVE state, or we did not set
+    // DownstreamConnection.
+    downstream->pop_downstream_connection();
+    handler_->signal_write();
+
+    return 0;
+  }
+
+  if (!downstream->request_submission_ready()) {
+    if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
+      // We have got all response body already.  Send it off.
+      downstream->pop_downstream_connection();
+      return 0;
+    }
+    // pushed stream is handled here
+    shutdown_stream(downstream, NGHTTP3_H3_INTERNAL_ERROR);
+    downstream->pop_downstream_connection();
+
+    handler_->signal_write();
+
+    return 0;
+  }
+
+  downstream->pop_downstream_connection();
+
+  downstream->add_retry();
+
+  std::unique_ptr<DownstreamConnection> dconn;
+
+  rv = 0;
+
+  if (no_retry || downstream->no_more_retry()) {
+    goto fail;
+  }
+
+  // downstream connection is clean; we can retry with new
+  // downstream connection.
+
+  for (;;) {
+    auto dconn = handler_->get_downstream_connection(rv, downstream);
+    if (!dconn) {
+      goto fail;
+    }
+
+    rv = downstream->attach_downstream_connection(std::move(dconn));
+    if (rv == 0) {
+      break;
+    }
+  }
+
+  rv = downstream->push_request_headers();
+  if (rv != 0) {
+    goto fail;
+  }
+
+  return 0;
+
+fail:
+  if (rv == SHRPX_ERR_TLS_REQUIRED) {
+    rv = on_downstream_abort_request_with_https_redirect(downstream);
+  } else {
+    rv = on_downstream_abort_request(downstream, 502);
+  }
+  if (rv != 0) {
+    shutdown_stream(downstream, NGHTTP3_H3_INTERNAL_ERROR);
+  }
+  downstream->pop_downstream_connection();
+
+  handler_->signal_write();
+
+  return 0;
+}
+
+void Http3Upstream::pause_read(IOCtrlReason reason) {}
+
+int Http3Upstream::resume_read(IOCtrlReason reason, Downstream *downstream,
+                               size_t consumed) {
+  consume(downstream->get_stream_id(), consumed);
+
+  auto &req = downstream->request();
+
+  req.consume(consumed);
+
+  handler_->signal_write();
+
+  return 0;
+}
+
+int Http3Upstream::send_reply(Downstream *downstream, const uint8_t *body,
+                              size_t bodylen) {
+  int rv;
+
+  nghttp3_data_reader data_read, *data_read_ptr = nullptr;
+
+  if (bodylen) {
+    data_read.read_data = downstream_read_data_callback;
+    data_read_ptr = &data_read;
+  }
+
+  const auto &resp = downstream->response();
+  auto config = get_config();
+  auto &httpconf = config->http;
+
+  auto &balloc = downstream->get_block_allocator();
+
+  const auto &headers = resp.fs.headers();
+  auto nva = std::vector<nghttp3_nv>();
+  // 2 for :status and server
+  nva.reserve(2 + headers.size() + httpconf.add_response_headers.size());
+
+  auto response_status = http2::stringify_status(balloc, resp.http_status);
+
+  nva.push_back(http3::make_nv_ls_nocopy(":status", response_status));
+
+  for (auto &kv : headers) {
+    if (kv.name.empty() || kv.name[0] == ':') {
+      continue;
+    }
+    switch (kv.token) {
+    case http2::HD_CONNECTION:
+    case http2::HD_KEEP_ALIVE:
+    case http2::HD_PROXY_CONNECTION:
+    case http2::HD_TE:
+    case http2::HD_TRANSFER_ENCODING:
+    case http2::HD_UPGRADE:
+      continue;
+    }
+    nva.push_back(http3::make_nv_nocopy(kv.name, kv.value, kv.no_index));
+  }
+
+  if (!resp.fs.header(http2::HD_SERVER)) {
+    nva.push_back(http3::make_nv_ls_nocopy("server", config->http.server_name));
+  }
+
+  for (auto &p : httpconf.add_response_headers) {
+    nva.push_back(http3::make_nv_nocopy(p.name, p.value));
+  }
+
+  rv = nghttp3_conn_submit_response(httpconn_, downstream->get_stream_id(),
+                                    nva.data(), nva.size(), data_read_ptr);
+  if (nghttp3_err_is_fatal(rv)) {
+    ULOG(FATAL, this) << "nghttp3_conn_submit_response() failed: "
+                      << nghttp3_strerror(rv);
+    return -1;
+  }
+
+  auto buf = downstream->get_response_buf();
+
+  buf->append(body, bodylen);
+
+  downstream->set_response_state(DownstreamState::MSG_COMPLETE);
+
+  if (data_read_ptr) {
+    downstream->reset_upstream_wtimer();
+  }
+
+  if (shutdown_stream_read(downstream->get_stream_id(), NGHTTP3_H3_NO_ERROR) !=
+      0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int Http3Upstream::initiate_push(Downstream *downstream, const StringRef &uri) {
+  return 0;
+}
+
+int Http3Upstream::response_riovec(struct iovec *iov, int iovcnt) const {
+  return 0;
+}
+
+void Http3Upstream::response_drain(size_t n) {}
+
+bool Http3Upstream::response_empty() const { return false; }
+
+Downstream *
+Http3Upstream::on_downstream_push_promise(Downstream *downstream,
+                                          int32_t promised_stream_id) {
+  return nullptr;
+}
+
+int Http3Upstream::on_downstream_push_promise_complete(
+    Downstream *downstream, Downstream *promised_downstream) {
+  return 0;
+}
+
+bool Http3Upstream::push_enabled() const { return false; }
+
+void Http3Upstream::cancel_premature_downstream(
+    Downstream *promised_downstream) {}
+
+int Http3Upstream::on_read(const UpstreamAddr *faddr,
+                           const Address &remote_addr,
+                           const Address &local_addr, const uint8_t *data,
+                           size_t datalen) {
+  int rv;
+  ngtcp2_pkt_info pi{};
+
+  auto path = ngtcp2_path{
+      {
+          local_addr.len,
+          const_cast<sockaddr *>(&local_addr.su.sa),
+      },
+      {
+          remote_addr.len,
+          const_cast<sockaddr *>(&remote_addr.su.sa),
+      },
+      const_cast<UpstreamAddr *>(faddr),
+  };
+
+  rv = ngtcp2_conn_read_pkt(conn_, &path, &pi, data, datalen, quic_timestamp());
+  if (rv != 0) {
+    switch (rv) {
+    case NGTCP2_ERR_DRAINING:
+      return -1;
+    case NGTCP2_ERR_RETRY: {
+      auto worker = handler_->get_worker();
+      auto quic_conn_handler = worker->get_quic_connection_handler();
+
+      uint32_t version;
+      const uint8_t *dcid, *scid;
+      size_t dcidlen, scidlen;
+
+      rv = ngtcp2_pkt_decode_version_cid(&version, &dcid, &dcidlen, &scid,
+                                         &scidlen, data, datalen,
+                                         SHRPX_QUIC_SCIDLEN);
+      if (rv != 0) {
+        return -1;
+      }
+
+      if (worker->get_graceful_shutdown()) {
+        ngtcp2_cid ini_dcid, ini_scid;
+
+        ngtcp2_cid_init(&ini_dcid, dcid, dcidlen);
+        ngtcp2_cid_init(&ini_scid, scid, scidlen);
+
+        quic_conn_handler->send_connection_close(
+            faddr, version, ini_dcid, ini_scid, remote_addr, local_addr,
+            NGTCP2_CONNECTION_REFUSED);
+
+        return -1;
+      }
+
+      retry_close_ = true;
+
+      quic_conn_handler->send_retry(handler_->get_upstream_addr(), version,
+                                    dcid, dcidlen, scid, scidlen, remote_addr,
+                                    local_addr);
+
+      return -1;
+    }
+    case NGTCP2_ERR_REQUIRED_TRANSPORT_PARAM:
+    case NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM:
+    case NGTCP2_ERR_TRANSPORT_PARAM:
+      // If rv indicates transport_parameters related error, we should
+      // send TRANSPORT_PARAMETER_ERROR even if last_error_.code is
+      // already set.  This is because OpenSSL might set Alert.
+      last_error_ = quic::err_transport(rv);
+      break;
+    case NGTCP2_ERR_DROP_CONN:
+      return -1;
+    default:
+      if (!last_error_.code) {
+        last_error_ = quic::err_transport(rv);
+      }
+    }
+
+    ULOG(ERROR, this) << "ngtcp2_conn_read_pkt: " << ngtcp2_strerror(rv);
+
+    return handle_error();
+  }
+
+  reset_idle_timer();
+
+  return 0;
+}
+
+int Http3Upstream::send_packet(const UpstreamAddr *faddr,
+                               const sockaddr *remote_sa, size_t remote_salen,
+                               const sockaddr *local_sa, size_t local_salen,
+                               const uint8_t *data, size_t datalen,
+                               size_t gso_size) {
+  auto rv = quic_send_packet(faddr, remote_sa, remote_salen, local_sa,
+                             local_salen, data, datalen, gso_size);
+  switch (rv) {
+  case 0:
+    return 0;
+    // With GSO, sendmsg may fail with EINVAL if UDP payload is too
+    // large.
+  case -EINVAL:
+  case -EMSGSIZE:
+    max_udp_payload_size_ = NGTCP2_MAX_UDP_PAYLOAD_SIZE;
+    break;
+  default:
+    break;
+  }
+
+  return -1;
+}
+
+int Http3Upstream::handle_error() {
+  if (ngtcp2_conn_is_in_closing_period(conn_)) {
+    return -1;
+  }
+
+  ngtcp2_path_storage ps;
+  ngtcp2_pkt_info pi;
+
+  ngtcp2_path_storage_zero(&ps);
+
+  auto ts = quic_timestamp();
+
+  conn_close_.resize(SHRPX_QUIC_CONN_CLOSE_PKTLEN);
+
+  ngtcp2_ssize nwrite;
+
+  if (last_error_.type == quic::ErrorType::Transport) {
+    nwrite = ngtcp2_conn_write_connection_close(
+        conn_, &ps.path, &pi, conn_close_.data(), conn_close_.size(),
+        last_error_.code, ts);
+    if (nwrite < 0) {
+      ULOG(ERROR, this) << "ngtcp2_conn_write_connection_close: "
+                        << ngtcp2_strerror(nwrite);
+      return -1;
+    }
+  } else {
+    nwrite = ngtcp2_conn_write_application_close(
+        conn_, &ps.path, &pi, conn_close_.data(), conn_close_.size(),
+        last_error_.code, ts);
+    if (nwrite < 0) {
+      ULOG(ERROR, this) << "ngtcp2_conn_write_application_close: "
+                        << ngtcp2_strerror(nwrite);
+      return -1;
+    }
+  }
+
+  conn_close_.resize(nwrite);
+
+  send_packet(static_cast<UpstreamAddr *>(ps.path.user_data),
+              ps.path.remote.addr, ps.path.remote.addrlen, ps.path.local.addr,
+              ps.path.local.addrlen, conn_close_.data(), nwrite, 0);
+
+  return -1;
+}
+
+int Http3Upstream::on_rx_secret(ngtcp2_crypto_level level,
+                                const uint8_t *secret, size_t secretlen) {
+  if (ngtcp2_crypto_derive_and_install_rx_key(conn_, nullptr, nullptr, nullptr,
+                                              level, secret, secretlen) != 0) {
+    ULOG(ERROR, this) << "ngtcp2_crypto_derive_and_install_rx_key failed";
+    return -1;
+  }
+
+  return 0;
+}
+
+int Http3Upstream::on_tx_secret(ngtcp2_crypto_level level,
+                                const uint8_t *secret, size_t secretlen) {
+  if (ngtcp2_crypto_derive_and_install_tx_key(conn_, nullptr, nullptr, nullptr,
+                                              level, secret, secretlen) != 0) {
+    ULOG(ERROR, this) << "ngtcp2_crypto_derive_and_install_tx_key failed";
+    return -1;
+  }
+
+  if (level == NGTCP2_CRYPTO_LEVEL_APPLICATION && setup_httpconn() != 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int Http3Upstream::add_crypto_data(ngtcp2_crypto_level level,
+                                   const uint8_t *data, size_t datalen) {
+  int rv = ngtcp2_conn_submit_crypto_data(conn_, level, data, datalen);
+
+  if (rv != 0) {
+    ULOG(ERROR, this) << "ngtcp2_conn_submit_crypto_data: "
+                      << ngtcp2_strerror(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+void Http3Upstream::set_tls_alert(uint8_t alert) { tls_alert_ = alert; }
+
+int Http3Upstream::handle_expiry() {
+  int rv;
+
+  auto ts = quic_timestamp();
+
+  rv = ngtcp2_conn_handle_expiry(conn_, ts);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "ngtcp2_conn_handle_expiry: " << ngtcp2_strerror(rv);
+    last_error_ = quic::err_transport(rv);
+    return handle_error();
+  }
+
+  return 0;
+}
+
+void Http3Upstream::reset_idle_timer() {
+  auto ts = quic_timestamp();
+  auto idle_ts = ngtcp2_conn_get_idle_expiry(conn_);
+
+  idle_timer_.repeat =
+      idle_ts > ts ? static_cast<ev_tstamp>(idle_ts - ts) / NGTCP2_SECONDS
+                   : 1e-9;
+
+  ev_timer_again(handler_->get_loop(), &idle_timer_);
+}
+
+void Http3Upstream::reset_timer() {
+  auto ts = quic_timestamp();
+  auto expiry_ts = ngtcp2_conn_get_expiry(conn_);
+
+  timer_.repeat = expiry_ts > ts
+                      ? static_cast<ev_tstamp>(expiry_ts - ts) / NGTCP2_SECONDS
+                      : 1e-9;
+
+  ev_timer_again(handler_->get_loop(), &timer_);
+}
+
+namespace {
+int http_deferred_consume(nghttp3_conn *conn, int64_t stream_id,
+                          size_t nconsumed, void *user_data,
+                          void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  upstream->consume(stream_id, nconsumed);
+
+  return 0;
+}
+} // namespace
+
+namespace {
+int http_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
+                           uint64_t datalen, void *user_data,
+                           void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+  auto downstream = static_cast<Downstream *>(stream_user_data);
+
+  assert(downstream);
+
+  if (upstream->http_acked_stream_data(downstream, datalen) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::http_acked_stream_data(Downstream *downstream,
+                                          uint64_t datalen) {
+  if (LOG_ENABLED(INFO)) {
+    ULOG(INFO, this) << "Stream " << downstream->get_stream_id() << " "
+                     << datalen << " bytes acknowledged";
+  }
+
+  auto body = downstream->get_response_buf();
+  auto drained = body->drain_mark(datalen);
+  (void)drained;
+
+  assert(datalen == drained);
+
+  if (downstream->resume_read(SHRPX_NO_BUFFER, datalen) != 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+namespace {
+int http_begin_request_headers(nghttp3_conn *conn, int64_t stream_id,
+                               void *user_data, void *stream_user_data) {
+  if (!ngtcp2_is_bidi_stream(stream_id)) {
+    return 0;
+  }
+
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+  upstream->http_begin_request_headers(stream_id);
+
+  return 0;
+}
+} // namespace
+
+namespace {
+int http_recv_request_header(nghttp3_conn *conn, int64_t stream_id,
+                             int32_t token, nghttp3_rcbuf *name,
+                             nghttp3_rcbuf *value, uint8_t flags,
+                             void *user_data, void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+  auto downstream = static_cast<Downstream *>(stream_user_data);
+
+  if (!downstream || downstream->get_stop_reading()) {
+    return 0;
+  }
+
+  if (upstream->http_recv_request_header(downstream, token, name, value,
+                                         flags) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::http_recv_request_header(Downstream *downstream,
+                                            int32_t h3token,
+                                            nghttp3_rcbuf *name,
+                                            nghttp3_rcbuf *value,
+                                            uint8_t flags) {
+  auto namebuf = nghttp3_rcbuf_get_buf(name);
+  auto valuebuf = nghttp3_rcbuf_get_buf(value);
+  auto &req = downstream->request();
+  auto config = get_config();
+  auto &httpconf = config->http;
+
+  if (req.fs.buffer_size() + namebuf.len + valuebuf.len >
+          httpconf.request_header_field_buffer ||
+      req.fs.num_fields() >= httpconf.max_request_header_fields) {
+    downstream->set_stop_reading(true);
+
+    if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
+      return 0;
+    }
+
+    if (LOG_ENABLED(INFO)) {
+      ULOG(INFO, this) << "Too large or many header field size="
+                       << req.fs.buffer_size() + namebuf.len + valuebuf.len
+                       << ", num=" << req.fs.num_fields() + 1;
+    }
+
+    if (error_reply(downstream, 431) != 0) {
+      return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+    }
+
+    return 0;
+  }
+
+  auto token = http2::lookup_token(namebuf.base, namebuf.len);
+  auto no_index = flags & NGHTTP3_NV_FLAG_NEVER_INDEX;
+
+  downstream->add_rcbuf(name);
+  downstream->add_rcbuf(value);
+
+  req.fs.add_header_token(StringRef{namebuf.base, namebuf.len},
+                          StringRef{valuebuf.base, valuebuf.len}, no_index,
+                          token);
+  return 0;
+}
+
+namespace {
+int http_end_request_headers(nghttp3_conn *conn, int64_t stream_id,
+                             void *user_data, void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+  auto handler = upstream->get_client_handler();
+  auto downstream = static_cast<Downstream *>(stream_user_data);
+
+  if (!downstream || downstream->get_stop_reading()) {
+    return 0;
+  }
+
+  if (upstream->http_end_request_headers(downstream) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+
+  downstream->reset_upstream_rtimer();
+  handler->stop_read_timer();
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::http_end_request_headers(Downstream *downstream) {
+  auto lgconf = log_config();
+  lgconf->update_tstamp(std::chrono::system_clock::now());
+  auto &req = downstream->request();
+  req.tstamp = lgconf->tstamp;
+
+  if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
+    return 0;
+  }
+
+  auto &nva = req.fs.headers();
+
+  if (LOG_ENABLED(INFO)) {
+    std::stringstream ss;
+    for (auto &nv : nva) {
+      if (nv.name == "authorization") {
+        ss << TTY_HTTP_HD << nv.name << TTY_RST << ": <redacted>\n";
+        continue;
+      }
+      ss << TTY_HTTP_HD << nv.name << TTY_RST << ": " << nv.value << "\n";
+    }
+    ULOG(INFO, this) << "HTTP request headers. stream_id="
+                     << downstream->get_stream_id() << "\n"
+                     << ss.str();
+  }
+
+  auto content_length = req.fs.header(http2::HD_CONTENT_LENGTH);
+  if (content_length) {
+    // libnghttp2 guarantees this can be parsed
+    req.fs.content_length = util::parse_uint(content_length->value);
+  }
+
+  // presence of mandatory header fields are guaranteed by libnghttp2.
+  auto authority = req.fs.header(http2::HD__AUTHORITY);
+  auto path = req.fs.header(http2::HD__PATH);
+  auto method = req.fs.header(http2::HD__METHOD);
+  auto scheme = req.fs.header(http2::HD__SCHEME);
+
+  auto method_token = http2::lookup_method_token(method->value);
+  if (method_token == -1) {
+    if (error_reply(downstream, 501) != 0) {
+      return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+    }
+    return 0;
+  }
+
+  auto faddr = handler_->get_upstream_addr();
+
+  auto config = get_config();
+
+  // For HTTP/2 proxy, we require :authority.
+  if (method_token != HTTP_CONNECT && config->http2_proxy &&
+      faddr->alt_mode == UpstreamAltMode::NONE && !authority) {
+    shutdown_stream(downstream, NGHTTP2_PROTOCOL_ERROR);
+    return 0;
+  }
+
+  req.method = method_token;
+  if (scheme) {
+    req.scheme = scheme->value;
+  }
+
+  // nghttp2 library guarantees either :authority or host exist
+  if (!authority) {
+    req.no_authority = true;
+    authority = req.fs.header(http2::HD_HOST);
+  }
+
+  if (authority) {
+    req.authority = authority->value;
+  }
+
+  if (path) {
+    if (method_token == HTTP_OPTIONS &&
+        path->value == StringRef::from_lit("*")) {
+      // Server-wide OPTIONS request.  Path is empty.
+    } else if (config->http2_proxy &&
+               faddr->alt_mode == UpstreamAltMode::NONE) {
+      req.path = path->value;
+    } else {
+      req.path = http2::rewrite_clean_path(downstream->get_block_allocator(),
+                                           path->value);
+    }
+  }
+
+  auto connect_proto = req.fs.header(http2::HD__PROTOCOL);
+  if (connect_proto) {
+    if (connect_proto->value != "websocket") {
+      if (error_reply(downstream, 400) != 0) {
+        return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+      }
+      return 0;
+    }
+    req.connect_proto = ConnectProto::WEBSOCKET;
+  }
+
+  // We are not sure that request has body or not at the moment.
+  req.http2_expect_body = true;
+
+  downstream->inspect_http2_request();
+
+  downstream->set_request_state(DownstreamState::HEADER_COMPLETE);
+
+#ifdef HAVE_MRUBY
+  auto upstream = downstream->get_upstream();
+  auto handler = upstream->get_client_handler();
+  auto worker = handler->get_worker();
+  auto mruby_ctx = worker->get_mruby_context();
+
+  if (mruby_ctx->run_on_request_proc(downstream) != 0) {
+    if (error_reply(downstream, 500) != 0) {
+      return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+    }
+    return 0;
+  }
+#endif // HAVE_MRUBY
+
+  if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
+    return 0;
+  }
+
+  start_downstream(downstream);
+
+  return 0;
+}
+
+void Http3Upstream::start_downstream(Downstream *downstream) {
+  if (downstream_queue_.can_activate(downstream->request().authority)) {
+    initiate_downstream(downstream);
+    return;
+  }
+
+  downstream_queue_.mark_blocked(downstream);
+}
+
+void Http3Upstream::initiate_downstream(Downstream *downstream) {
+  int rv;
+
+  DownstreamConnection *dconn_ptr;
+
+  for (;;) {
+    auto dconn = handler_->get_downstream_connection(rv, downstream);
+    if (!dconn) {
+      if (rv == SHRPX_ERR_TLS_REQUIRED) {
+        rv = redirect_to_https(downstream);
+      } else {
+        rv = error_reply(downstream, 502);
+      }
+      if (rv != 0) {
+        shutdown_stream(downstream, NGHTTP3_H3_INTERNAL_ERROR);
+      }
+
+      downstream->set_request_state(DownstreamState::CONNECT_FAIL);
+      downstream_queue_.mark_failure(downstream);
+
+      return;
+    }
+
+#ifdef HAVE_MRUBY
+    dconn_ptr = dconn.get();
+#endif // HAVE_MRUBY
+    rv = downstream->attach_downstream_connection(std::move(dconn));
+    if (rv == 0) {
+      break;
+    }
+  }
+
+#ifdef HAVE_MRUBY
+  const auto &group = dconn_ptr->get_downstream_addr_group();
+  if (group) {
+    const auto &mruby_ctx = group->shared_addr->mruby_ctx;
+    if (mruby_ctx->run_on_request_proc(downstream) != 0) {
+      if (error_reply(downstream, 500) != 0) {
+        shutdown_stream(downstream, NGHTTP3_H3_INTERNAL_ERROR);
+      }
+
+      downstream_queue_.mark_failure(downstream);
+
+      return;
+    }
+
+    if (downstream->get_response_state() == DownstreamState::MSG_COMPLETE) {
+      return;
+    }
+  }
+#endif // HAVE_MRUBY
+
+  rv = downstream->push_request_headers();
+  if (rv != 0) {
+
+    if (error_reply(downstream, 502) != 0) {
+      shutdown_stream(downstream, NGHTTP3_H3_INTERNAL_ERROR);
+    }
+
+    downstream_queue_.mark_failure(downstream);
+
+    return;
+  }
+
+  downstream_queue_.mark_active(downstream);
+
+  auto &req = downstream->request();
+  if (!req.http2_expect_body) {
+    rv = downstream->end_upload_data();
+    if (rv != 0) {
+      shutdown_stream(downstream, NGHTTP3_H3_INTERNAL_ERROR);
+    }
+  }
+}
+
+namespace {
+int http_recv_data(nghttp3_conn *conn, int64_t stream_id, const uint8_t *data,
+                   size_t datalen, void *user_data, void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+  auto downstream = static_cast<Downstream *>(stream_user_data);
+
+  if (upstream->http_recv_data(downstream, data, datalen) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::http_recv_data(Downstream *downstream, const uint8_t *data,
+                                  size_t datalen) {
+  downstream->reset_upstream_rtimer();
+
+  if (downstream->push_upload_data_chunk(data, datalen) != 0) {
+    if (downstream->get_response_state() != DownstreamState::MSG_COMPLETE) {
+      shutdown_stream(downstream, NGHTTP3_H3_INTERNAL_ERROR);
+    }
+
+    consume(downstream->get_stream_id(), datalen);
+
+    return 0;
+  }
+
+  return 0;
+}
+
+namespace {
+int http_end_stream(nghttp3_conn *conn, int64_t stream_id, void *user_data,
+                    void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+  auto downstream = static_cast<Downstream *>(stream_user_data);
+
+  if (!downstream || downstream->get_stop_reading()) {
+    return 0;
+  }
+
+  if (upstream->http_end_stream(downstream) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::http_end_stream(Downstream *downstream) {
+  downstream->disable_upstream_rtimer();
+
+  if (downstream->end_upload_data() != 0) {
+    if (downstream->get_response_state() != DownstreamState::MSG_COMPLETE) {
+      shutdown_stream(downstream, NGHTTP2_INTERNAL_ERROR);
+    }
+  }
+
+  downstream->set_request_state(DownstreamState::MSG_COMPLETE);
+
+  return 0;
+}
+
+namespace {
+int http_stream_close(nghttp3_conn *conn, int64_t stream_id,
+                      uint64_t app_error_code, void *conn_user_data,
+                      void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(conn_user_data);
+  auto downstream = static_cast<Downstream *>(stream_user_data);
+
+  if (!downstream) {
+    return 0;
+  }
+
+  if (upstream->http_stream_close(downstream, app_error_code) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::http_stream_close(Downstream *downstream,
+                                     uint64_t app_error_code) {
+  auto stream_id = downstream->get_stream_id();
+
+  if (LOG_ENABLED(INFO)) {
+    ULOG(INFO, this) << "Stream stream_id=" << stream_id
+                     << " is being closed with app_error_code="
+                     << app_error_code;
+
+    auto body = downstream->get_response_buf();
+
+    ULOG(INFO, this) << "response unacked_left=" << body->rleft()
+                     << " not_sent=" << body->rleft_mark();
+  }
+
+  auto &req = downstream->request();
+
+  consume(stream_id, req.unconsumed_body_length);
+
+  req.unconsumed_body_length = 0;
+
+  ngtcp2_conn_extend_max_streams_bidi(conn_, 1);
+
+  if (downstream->get_request_state() == DownstreamState::CONNECT_FAIL) {
+    remove_downstream(downstream);
+    // downstream was deleted
+
+    return 0;
+  }
+
+  if (downstream->can_detach_downstream_connection()) {
+    // Keep-alive
+    downstream->detach_downstream_connection();
+  }
+
+  downstream->set_request_state(DownstreamState::STREAM_CLOSED);
+
+  // At this point, downstream read may be paused.
+
+  // If shrpx_downstream::push_request_headers() failed, the
+  // error is handled here.
+  remove_downstream(downstream);
+  // downstream was deleted
+
+  return 0;
+}
+
+namespace {
+int http_send_stop_sending(nghttp3_conn *conn, int64_t stream_id,
+                           uint64_t app_error_code, void *user_data,
+                           void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  if (upstream->http_send_stop_sending(stream_id, app_error_code) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::http_send_stop_sending(int64_t stream_id,
+                                          uint64_t app_error_code) {
+  auto rv = ngtcp2_conn_shutdown_stream_read(conn_, stream_id, app_error_code);
+  if (ngtcp2_err_is_fatal(rv)) {
+    ULOG(ERROR, this) << "ngtcp2_conn_shutdown_stream_read: "
+                      << ngtcp2_strerror(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+namespace {
+int http_reset_stream(nghttp3_conn *conn, int64_t stream_id,
+                      uint64_t app_error_code, void *user_data,
+                      void *stream_user_data) {
+  auto upstream = static_cast<Http3Upstream *>(user_data);
+
+  if (upstream->http_reset_stream(stream_id, app_error_code) != 0) {
+    return NGHTTP3_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+} // namespace
+
+int Http3Upstream::http_reset_stream(int64_t stream_id,
+                                     uint64_t app_error_code) {
+  auto rv = ngtcp2_conn_shutdown_stream_write(conn_, stream_id, app_error_code);
+  if (ngtcp2_err_is_fatal(rv)) {
+    ULOG(ERROR, this) << "ngtcp2_conn_shutdown_stream_write: "
+                      << ngtcp2_strerror(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+int Http3Upstream::setup_httpconn() {
+  int rv;
+
+  if (ngtcp2_conn_get_max_local_streams_uni(conn_) < 3) {
+    return -1;
+  }
+
+  nghttp3_callbacks callbacks{
+      shrpx::http_acked_stream_data,
+      shrpx::http_stream_close,
+      shrpx::http_recv_data,
+      http_deferred_consume,
+      shrpx::http_begin_request_headers,
+      shrpx::http_recv_request_header,
+      shrpx::http_end_request_headers,
+      nullptr, // begin_trailers
+      nullptr, // recv_trailer
+      nullptr, // end_trailers
+      shrpx::http_send_stop_sending,
+      shrpx::http_end_stream,
+      shrpx::http_reset_stream,
+  };
+
+  auto config = get_config();
+
+  nghttp3_settings settings;
+  nghttp3_settings_default(&settings);
+  settings.qpack_max_table_capacity = 4_k;
+
+  if (!config->http2_proxy) {
+    settings.enable_connect_protocol = 1;
+  }
+
+  auto mem = nghttp3_mem_default();
+
+  rv = nghttp3_conn_server_new(&httpconn_, &callbacks, &settings, mem, this);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "nghttp3_conn_server_new: " << nghttp3_strerror(rv);
+    return -1;
+  }
+
+  ngtcp2_transport_params params;
+  ngtcp2_conn_get_local_transport_params(conn_, &params);
+
+  nghttp3_conn_set_max_client_streams_bidi(httpconn_,
+                                           params.initial_max_streams_bidi);
+
+  int64_t ctrl_stream_id;
+
+  rv = ngtcp2_conn_open_uni_stream(conn_, &ctrl_stream_id, nullptr);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "ngtcp2_conn_open_uni_stream: " << ngtcp2_strerror(rv);
+    return -1;
+  }
+
+  rv = nghttp3_conn_bind_control_stream(httpconn_, ctrl_stream_id);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "nghttp3_conn_bind_control_stream: "
+                      << nghttp3_strerror(rv);
+    return -1;
+  }
+
+  int64_t qpack_enc_stream_id, qpack_dec_stream_id;
+
+  rv = ngtcp2_conn_open_uni_stream(conn_, &qpack_enc_stream_id, nullptr);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "ngtcp2_conn_open_uni_stream: " << ngtcp2_strerror(rv);
+    return -1;
+  }
+
+  rv = ngtcp2_conn_open_uni_stream(conn_, &qpack_dec_stream_id, nullptr);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "ngtcp2_conn_open_uni_stream: " << ngtcp2_strerror(rv);
+    return -1;
+  }
+
+  rv = nghttp3_conn_bind_qpack_streams(httpconn_, qpack_enc_stream_id,
+                                       qpack_dec_stream_id);
+  if (rv != 0) {
+    ULOG(ERROR, this) << "nghttp3_conn_bind_qpack_streams: "
+                      << nghttp3_strerror(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+int Http3Upstream::error_reply(Downstream *downstream,
+                               unsigned int status_code) {
+  int rv;
+  auto &resp = downstream->response();
+
+  auto &balloc = downstream->get_block_allocator();
+
+  auto html = http::create_error_html(balloc, status_code);
+  resp.http_status = status_code;
+  auto body = downstream->get_response_buf();
+  body->append(html);
+  downstream->set_response_state(DownstreamState::MSG_COMPLETE);
+
+  nghttp3_data_reader data_read;
+  data_read.read_data = downstream_read_data_callback;
+
+  auto lgconf = log_config();
+  lgconf->update_tstamp(std::chrono::system_clock::now());
+
+  auto response_status = http2::stringify_status(balloc, status_code);
+  auto content_length = util::make_string_ref_uint(balloc, html.size());
+  auto date = make_string_ref(balloc, lgconf->tstamp->time_http);
+
+  auto nva = std::array<nghttp3_nv, 5>{
+      {http3::make_nv_ls_nocopy(":status", response_status),
+       http3::make_nv_ll("content-type", "text/html; charset=UTF-8"),
+       http3::make_nv_ls_nocopy("server", get_config()->http.server_name),
+       http3::make_nv_ls_nocopy("content-length", content_length),
+       http3::make_nv_ls_nocopy("date", date)}};
+
+  rv = nghttp3_conn_submit_response(httpconn_, downstream->get_stream_id(),
+                                    nva.data(), nva.size(), &data_read);
+  if (nghttp3_err_is_fatal(rv)) {
+    ULOG(FATAL, this) << "nghttp3_conn_submit_response() failed: "
+                      << nghttp3_strerror(rv);
+    return -1;
+  }
+
+  downstream->reset_upstream_wtimer();
+
+  if (shutdown_stream_read(downstream->get_stream_id(), NGHTTP3_H3_NO_ERROR) !=
+      0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int Http3Upstream::shutdown_stream(Downstream *downstream,
+                                   uint64_t app_error_code) {
+  auto stream_id = downstream->get_stream_id();
+
+  if (LOG_ENABLED(INFO)) {
+    ULOG(INFO, this) << "Shutdown stream_id=" << stream_id
+                     << " with app_error_code=" << app_error_code;
+  }
+
+  auto rv = ngtcp2_conn_shutdown_stream(conn_, stream_id, app_error_code);
+  if (rv != 0) {
+    ULOG(FATAL, this) << "ngtcp2_conn_shutdown_stream() failed: "
+                      << ngtcp2_strerror(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+int Http3Upstream::shutdown_stream_read(int64_t stream_id,
+                                        uint64_t app_error_code) {
+  auto rv =
+      ngtcp2_conn_shutdown_stream_read(conn_, stream_id, NGHTTP3_H3_NO_ERROR);
+  if (ngtcp2_err_is_fatal(rv)) {
+    ULOG(FATAL, this) << "ngtcp2_conn_shutdown_stream_read: "
+                      << ngtcp2_strerror(rv);
+    return -1;
+  }
+
+  return 0;
+}
+
+int Http3Upstream::redirect_to_https(Downstream *downstream) {
+  auto &req = downstream->request();
+  if (req.regular_connect_method() || req.scheme != "http") {
+    return error_reply(downstream, 400);
+  }
+
+  auto authority = util::extract_host(req.authority);
+  if (authority.empty()) {
+    return error_reply(downstream, 400);
+  }
+
+  auto &balloc = downstream->get_block_allocator();
+  auto config = get_config();
+  auto &httpconf = config->http;
+
+  StringRef loc;
+  if (httpconf.redirect_https_port == StringRef::from_lit("443")) {
+    loc = concat_string_ref(balloc, StringRef::from_lit("https://"), authority,
+                            req.path);
+  } else {
+    loc = concat_string_ref(balloc, StringRef::from_lit("https://"), authority,
+                            StringRef::from_lit(":"),
+                            httpconf.redirect_https_port, req.path);
+  }
+
+  auto &resp = downstream->response();
+  resp.http_status = 308;
+  resp.fs.add_header_token(StringRef::from_lit("location"), loc, false,
+                           http2::HD_LOCATION);
+
+  return send_reply(downstream, nullptr, 0);
+}
+
+void Http3Upstream::consume(int64_t stream_id, size_t nconsumed) {
+  ngtcp2_conn_extend_max_stream_offset(conn_, stream_id, nconsumed);
+  ngtcp2_conn_extend_max_offset(conn_, nconsumed);
+}
+
+void Http3Upstream::remove_downstream(Downstream *downstream) {
+  if (downstream->accesslog_ready()) {
+    handler_->write_accesslog(downstream);
+  }
+
+  nghttp3_conn_set_stream_user_data(httpconn_, downstream->get_stream_id(),
+                                    nullptr);
+
+  auto next_downstream = downstream_queue_.remove_and_get_blocked(downstream);
+
+  if (next_downstream) {
+    initiate_downstream(next_downstream);
+  }
+
+  if (downstream_queue_.get_downstreams() == nullptr) {
+    // There is no downstream at the moment.  Start idle timer now.
+    handler_->repeat_read_timer();
+  }
+}
+
+void Http3Upstream::log_response_headers(
+    Downstream *downstream, const std::vector<nghttp3_nv> &nva) const {
+  std::stringstream ss;
+  for (auto &nv : nva) {
+    ss << TTY_HTTP_HD << StringRef{nv.name, nv.namelen} << TTY_RST << ": "
+       << StringRef{nv.value, nv.valuelen} << "\n";
+  }
+  ULOG(INFO, this) << "HTTP response headers. stream_id="
+                   << downstream->get_stream_id() << "\n"
+                   << ss.str();
+}
+
+int Http3Upstream::check_shutdown() {
+  auto worker = handler_->get_worker();
+
+  if (!worker->get_graceful_shutdown()) {
+    return 0;
+  }
+
+  ev_prepare_stop(handler_->get_loop(), &prep_);
+
+  return start_graceful_shutdown();
+}
+
+int Http3Upstream::start_graceful_shutdown() {
+  int rv;
+
+  if (ev_is_active(&shutdown_timer_)) {
+    return 0;
+  }
+
+  rv = nghttp3_conn_submit_shutdown_notice(httpconn_);
+  if (rv != 0) {
+    ULOG(FATAL, this) << "nghttp3_conn_submit_shutdown_notice: "
+                      << nghttp3_strerror(rv);
+    return -1;
+  }
+
+  handler_->signal_write();
+
+  auto t = ngtcp2_conn_get_pto(conn_);
+
+  ev_timer_set(&shutdown_timer_, static_cast<ev_tstamp>(t * 3) / NGTCP2_SECONDS,
+               0.);
+  ev_timer_start(handler_->get_loop(), &shutdown_timer_);
+
+  return 0;
+}
+
+int Http3Upstream::submit_goaway() {
+  int rv;
+
+  rv = nghttp3_conn_shutdown(httpconn_);
+  if (rv != 0) {
+    ULOG(FATAL, this) << "nghttp3_conn_shutdown: " << nghttp3_strerror(rv);
+    return -1;
+  }
+
+  handler_->signal_write();
+
+  return 0;
+}
+
+void Http3Upstream::idle_close() { idle_close_ = true; }
+
+int Http3Upstream::open_qlog_file(const StringRef &dir,
+                                  const ngtcp2_cid &scid) const {
+  std::array<char, sizeof("20141115T125824.741+0900")> buf;
+
+  auto path = dir.str();
+  path += '/';
+  path +=
+      util::format_iso8601_basic(buf.data(), std::chrono::system_clock::now());
+  path += '-';
+  path += util::format_hex(scid.data, scid.datalen);
+  path += ".qlog";
+
+  int fd;
+
+#ifdef O_CLOEXEC
+  while ((fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
+                    S_IRUSR | S_IWUSR | S_IRGRP)) == -1 &&
+         errno == EINTR)
+    ;
+#else  // !O_CLOEXEC
+  while ((fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
+                    S_IRUSR | S_IWUSR | S_IRGRP)) == -1 &&
+         errno == EINTR)
+    ;
+
+  if (fd != -1) {
+    util::make_socket_closeonexec(fd);
+  }
+#endif // !O_CLOEXEC
+
+  if (fd == -1) {
+    auto error = errno;
+    ULOG(ERROR, this) << "Failed to open qlog file " << path
+                      << ": errno=" << error;
+    return -1;
+  }
+
+  return fd;
+}
+
+} // namespace shrpx
diff --git a/src/shrpx_http3_upstream.h b/src/shrpx_http3_upstream.h
new file mode 100644 (file)
index 0000000..b2935af
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef SHRPX_HTTP3_UPSTREAM_H
+#define SHRPX_HTTP3_UPSTREAM_H
+
+#include "shrpx.h"
+
+#include <ngtcp2/ngtcp2.h>
+#include <nghttp3/nghttp3.h>
+
+#include "shrpx_upstream.h"
+#include "shrpx_downstream_queue.h"
+#include "quic.h"
+#include "network.h"
+
+using namespace nghttp2;
+
+namespace shrpx {
+
+struct UpstreamAddr;
+
+class Http3Upstream : public Upstream {
+public:
+  Http3Upstream(ClientHandler *handler);
+  virtual ~Http3Upstream();
+
+  virtual int on_read();
+  virtual int on_write();
+  virtual int on_timeout(Downstream *downstream);
+  virtual int on_downstream_abort_request(Downstream *downstream,
+                                          unsigned int status_code);
+  virtual int
+  on_downstream_abort_request_with_https_redirect(Downstream *downstream);
+  virtual int downstream_read(DownstreamConnection *dconn);
+  virtual int downstream_write(DownstreamConnection *dconn);
+  virtual int downstream_eof(DownstreamConnection *dconn);
+  virtual int downstream_error(DownstreamConnection *dconn, int events);
+  virtual ClientHandler *get_client_handler() const;
+
+  virtual int on_downstream_header_complete(Downstream *downstream);
+  virtual int on_downstream_body(Downstream *downstream, const uint8_t *data,
+                                 size_t len, bool flush);
+  virtual int on_downstream_body_complete(Downstream *downstream);
+
+  virtual void on_handler_delete();
+  virtual int on_downstream_reset(Downstream *downstream, bool no_retry);
+
+  virtual void pause_read(IOCtrlReason reason);
+  virtual int resume_read(IOCtrlReason reason, Downstream *downstream,
+                          size_t consumed);
+  virtual int send_reply(Downstream *downstream, const uint8_t *body,
+                         size_t bodylen);
+
+  virtual int initiate_push(Downstream *downstream, const StringRef &uri);
+
+  virtual int response_riovec(struct iovec *iov, int iovcnt) const;
+  virtual void response_drain(size_t n);
+  virtual bool response_empty() const;
+
+  virtual Downstream *on_downstream_push_promise(Downstream *downstream,
+                                                 int32_t promised_stream_id);
+  virtual int
+  on_downstream_push_promise_complete(Downstream *downstream,
+                                      Downstream *promised_downstream);
+  virtual bool push_enabled() const;
+  virtual void cancel_premature_downstream(Downstream *promised_downstream);
+
+  int init(const UpstreamAddr *faddr, const Address &remote_addr,
+           const Address &local_addr, const ngtcp2_pkt_hd &initial_hd,
+           const ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen);
+
+  int on_read(const UpstreamAddr *faddr, const Address &remote_addr,
+              const Address &local_addr, const uint8_t *data, size_t datalen);
+
+  int write_streams();
+
+  int on_rx_secret(ngtcp2_crypto_level level, const uint8_t *secret,
+                   size_t secretlen);
+  int on_tx_secret(ngtcp2_crypto_level level, const uint8_t *secret,
+                   size_t secretlen);
+
+  int add_crypto_data(ngtcp2_crypto_level level, const uint8_t *data,
+                      size_t datalen);
+
+  void set_tls_alert(uint8_t alert);
+
+  int handle_error();
+
+  int handle_expiry();
+  void reset_idle_timer();
+  void reset_timer();
+
+  int setup_httpconn();
+  void add_pending_downstream(std::unique_ptr<Downstream> downstream);
+  int recv_stream_data(uint32_t flags, int64_t stream_id, const uint8_t *data,
+                       size_t datalen);
+  int acked_stream_data_offset(int64_t stream_id, uint64_t datalen);
+  int extend_max_stream_data(int64_t stream_id);
+  void extend_max_remote_streams_bidi(uint64_t max_streams);
+  int error_reply(Downstream *downstream, unsigned int status_code);
+  void http_begin_request_headers(int64_t stream_id);
+  int http_recv_request_header(Downstream *downstream, int32_t token,
+                               nghttp3_rcbuf *name, nghttp3_rcbuf *value,
+                               uint8_t flags);
+  int http_end_request_headers(Downstream *downstream);
+  int http_end_stream(Downstream *downstream);
+  void start_downstream(Downstream *downstream);
+  void initiate_downstream(Downstream *downstream);
+  int shutdown_stream(Downstream *downstream, uint64_t app_error_code);
+  int shutdown_stream_read(int64_t stream_id, uint64_t app_error_code);
+  int redirect_to_https(Downstream *downstream);
+  int http_stream_close(Downstream *downstream, uint64_t app_error_code);
+  void consume(int64_t stream_id, size_t nconsumed);
+  void remove_downstream(Downstream *downstream);
+  int stream_close(int64_t stream_id, uint64_t app_error_code);
+  void log_response_headers(Downstream *downstream,
+                            const std::vector<nghttp3_nv> &nva) const;
+  int http_acked_stream_data(Downstream *downstream, uint64_t datalen);
+  int http_shutdown_stream_read(int64_t stream_id);
+  int http_reset_stream(int64_t stream_id, uint64_t app_error_code);
+  int http_send_stop_sending(int64_t stream_id, uint64_t app_error_code);
+  int http_recv_data(Downstream *downstream, const uint8_t *data,
+                     size_t datalen);
+  int handshake_completed();
+  int check_shutdown();
+  int start_graceful_shutdown();
+  int submit_goaway();
+  void idle_close();
+  int send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
+                  size_t remote_salen, const sockaddr *local_sa,
+                  size_t local_salen, const uint8_t *data, size_t datalen,
+                  size_t gso_size);
+
+  void qlog_write(const void *data, size_t datalen, bool fin);
+  int open_qlog_file(const StringRef &dir, const ngtcp2_cid &scid) const;
+
+private:
+  ClientHandler *handler_;
+  ev_timer timer_;
+  ev_timer idle_timer_;
+  ev_timer shutdown_timer_;
+  ev_prepare prep_;
+  size_t max_udp_payload_size_;
+  int qlog_fd_;
+  ngtcp2_cid hashed_scid_;
+  ngtcp2_conn *conn_;
+  quic::Error last_error_;
+  uint8_t tls_alert_;
+  nghttp3_conn *httpconn_;
+  DownstreamQueue downstream_queue_;
+  bool idle_close_;
+  bool retry_close_;
+  std::vector<uint8_t> conn_close_;
+};
+
+} // namespace shrpx
+
+#endif // SHRPX_HTTP3_UPSTREAM_H
index f68cfcf..8c4fe6e 100644 (file)
@@ -24,6 +24,8 @@
  */
 #include "shrpx_http_downstream_connection.h"
 
+#include <openssl/rand.h>
+
 #include "shrpx_client_handler.h"
 #include "shrpx_upstream.h"
 #include "shrpx_downstream.h"
@@ -521,7 +523,9 @@ int HttpDownstreamConnection::push_request_headers() {
       (xffconf.strip_incoming ? http2::HDOP_STRIP_X_FORWARDED_FOR : 0) |
       (xfpconf.strip_incoming ? http2::HDOP_STRIP_X_FORWARDED_PROTO : 0) |
       (earlydataconf.strip_incoming ? http2::HDOP_STRIP_EARLY_DATA : 0) |
-      (req.http_major == 2 ? http2::HDOP_STRIP_SEC_WEBSOCKET_KEY : 0);
+      ((req.http_major == 3 || req.http_major == 2)
+           ? http2::HDOP_STRIP_SEC_WEBSOCKET_KEY
+           : 0);
 
   http2::build_http1_headers_from_headers(buf, req.fs.headers(), build_flags);
 
@@ -541,10 +545,11 @@ int HttpDownstreamConnection::push_request_headers() {
   }
 
   if (req.connect_proto == ConnectProto::WEBSOCKET) {
-    if (req.http_major == 2) {
+    if (req.http_major == 3 || req.http_major == 2) {
       std::array<uint8_t, 16> nonce;
-      util::random_bytes(std::begin(nonce), std::end(nonce),
-                         worker_->get_randgen());
+      if (RAND_bytes(nonce.data(), nonce.size()) != 1) {
+        return -1;
+      }
       auto iov = make_byte_ref(balloc, base64::encode_length(nonce.size()) + 1);
       auto p = base64::encode(std::begin(nonce), std::end(nonce), iov.base);
       *p = '\0';
@@ -891,8 +896,7 @@ int htp_msg_begincb(llhttp_t *htp) {
   auto downstream = static_cast<Downstream *>(htp->data);
 
   if (downstream->get_response_state() != DownstreamState::INITIAL) {
-    llhttp_set_error_reason(htp, "HTTP message started when it shouldn't");
-    return HPE_USER;
+    return -1;
   }
 
   return 0;
@@ -1214,6 +1218,18 @@ int HttpDownstreamConnection::read_clear() {
     }
 
     if (nread < 0) {
+      if (nread == SHRPX_ERR_EOF && !downstream_->get_upgraded()) {
+        auto htperr = llhttp_finish(&response_htp_);
+        if (htperr != HPE_OK) {
+          if (LOG_ENABLED(INFO)) {
+            DCLOG(INFO, this) << "HTTP response ended prematurely: "
+                              << llhttp_errno_name(htperr);
+          }
+
+          return -1;
+        }
+      }
+
       return nread;
     }
 
@@ -1333,6 +1349,18 @@ int HttpDownstreamConnection::read_tls() {
     }
 
     if (nread < 0) {
+      if (nread == SHRPX_ERR_EOF && !downstream_->get_upgraded()) {
+        auto htperr = llhttp_finish(&response_htp_);
+        if (htperr != HPE_OK) {
+          if (LOG_ENABLED(INFO)) {
+            DCLOG(INFO, this) << "HTTP response ended prematurely: "
+                              << llhttp_errno_name(htperr);
+          }
+
+          return -1;
+        }
+      }
+
       return nread;
     }
 
index ba3fad9..7a9c63a 100644 (file)
@@ -118,4 +118,40 @@ void test_shrpx_http_create_affinity_cookie(void) {
   CU_ASSERT("charlie=01111111; Path=bar; Secure" == c);
 }
 
+void test_shrpx_http_create_altsvc_header_value(void) {
+  {
+    BlockAllocator balloc(1024, 1024);
+    std::vector<AltSvc> altsvcs{
+        AltSvc{
+            .protocol_id = StringRef::from_lit("h3"),
+            .host = StringRef::from_lit("127.0.0.1"),
+            .service = StringRef::from_lit("443"),
+            .params = StringRef::from_lit("ma=3600"),
+        },
+    };
+
+    CU_ASSERT(R"(h3="127.0.0.1:443"; ma=3600)" ==
+              http::create_altsvc_header_value(balloc, altsvcs));
+  }
+
+  {
+    BlockAllocator balloc(1024, 1024);
+    std::vector<AltSvc> altsvcs{
+        AltSvc{
+            .protocol_id = StringRef::from_lit("h3"),
+            .service = StringRef::from_lit("443"),
+            .params = StringRef::from_lit("ma=3600"),
+        },
+        AltSvc{
+            .protocol_id = StringRef::from_lit("h3%"),
+            .host = StringRef::from_lit("\"foo\""),
+            .service = StringRef::from_lit("4433"),
+        },
+    };
+
+    CU_ASSERT(R"(h3=":443"; ma=3600, h3%25="\"foo\":4433")" ==
+              http::create_altsvc_header_value(balloc, altsvcs));
+  }
+}
+
 } // namespace shrpx
index 8bd8395..8c3b1d9 100644 (file)
@@ -34,6 +34,7 @@ namespace shrpx {
 void test_shrpx_http_create_forwarded(void);
 void test_shrpx_http_create_via_header_value(void);
 void test_shrpx_http_create_affinity_cookie(void);
+void test_shrpx_http_create_altsvc_header_value(void);
 
 } // namespace shrpx
 
index 34a5504..d9bef5e 100644 (file)
@@ -559,8 +559,7 @@ int htp_msg_completecb(llhttp_t *htp) {
       // signal_write() to run on_write().
       return HPE_PAUSED;
     }
-    llhttp_set_error_reason(htp, "could not finish request body");
-    return HPE_USER;
+    return -1;
   }
 
   if (handler->get_http2_upgrade_allowed() &&
@@ -748,6 +747,13 @@ int HttpsUpstream::on_write() {
       handler_->repeat_read_timer();
 
       return resume_read(SHRPX_NO_BUFFER, nullptr, 0);
+    } else {
+      // If the request is not complete, close the connection.
+      delete_downstream();
+
+      handler_->set_should_close_after_write(true);
+
+      return 0;
     }
   }
 
@@ -1049,18 +1055,6 @@ std::unique_ptr<Downstream> HttpsUpstream::pop_downstream() {
   return std::unique_ptr<Downstream>(downstream_.release());
 }
 
-namespace {
-void write_altsvc(DefaultMemchunks *buf, BlockAllocator &balloc,
-                  const AltSvc &altsvc) {
-  buf->append(util::percent_encode_token(balloc, altsvc.protocol_id));
-  buf->append("=\"");
-  buf->append(util::quote_string(balloc, altsvc.host));
-  buf->append(':');
-  buf->append(altsvc.service);
-  buf->append('"');
-}
-} // namespace
-
 int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
   if (LOG_ENABLED(INFO)) {
     if (downstream->get_non_final_response()) {
@@ -1219,13 +1213,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
     // We won't change or alter alt-svc from backend for now
     if (!httpconf.altsvcs.empty()) {
       buf->append("Alt-Svc: ");
-
-      auto &altsvcs = httpconf.altsvcs;
-      write_altsvc(buf, downstream->get_block_allocator(), altsvcs[0]);
-      for (size_t i = 1; i < altsvcs.size(); ++i) {
-        buf->append(", ");
-        write_altsvc(buf, downstream->get_block_allocator(), altsvcs[i]);
-      }
+      buf->append(httpconf.altsvc_header_value);
       buf->append("\r\n");
     }
   }
index 58fcb5f..fe626d6 100644 (file)
@@ -189,7 +189,7 @@ Log::~Log() {
 
   lgconf->update_tstamp_millis(std::chrono::system_clock::now());
 
-  // Error log format: <datetime> <master-pid> <current-pid>
+  // Error log format: <datetime> <main-pid> <current-pid>
   // <thread-id> <level> (<filename>:<line>) <msg>
   rv = snprintf(buf, sizeof(buf), "%s %d %d %s %s%s%s (%s:%d) %.*s\n",
                 lgconf->tstamp->time_iso8601.c_str(), config->pid, lgconf->pid,
@@ -251,7 +251,7 @@ Log &Log::operator<<(long long n) {
     return *this;
   }
   *last_++ = '-';
-  *last_ += nlen;
+  last_ += nlen;
   update_full();
 
   auto p = last_ - 1;
@@ -595,14 +595,17 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
   auto downstream_addr = downstream->get_addr();
   auto method = req.method == -1 ? StringRef::from_lit("<unknown>")
                                  : http2::to_method_string(req.method);
-  auto path = req.method == HTTP_CONNECT
-                  ? req.authority
-                  : config->http2_proxy
-                        ? construct_absolute_request_uri(balloc, req)
-                        : req.path.empty() ? req.method == HTTP_OPTIONS
-                                                 ? StringRef::from_lit("*")
-                                                 : StringRef::from_lit("-")
-                                           : req.path;
+  auto path =
+      req.method == HTTP_CONNECT ? req.authority
+      : config->http2_proxy      ? construct_absolute_request_uri(balloc, req)
+      : req.path.empty() ? req.method == HTTP_OPTIONS ? StringRef::from_lit("*")
+                                                      : StringRef::from_lit("-")
+                         : req.path;
+  auto path_without_query =
+      req.method == HTTP_CONNECT
+          ? path
+          : StringRef{std::begin(path),
+                      std::find(std::begin(path), std::end(path), '?')};
 
   auto p = std::begin(buf);
   auto last = std::end(buf) - 2;
@@ -632,6 +635,23 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
         std::tie(p, last) = copy(req.http_minor, p, last);
       }
       break;
+    case LogFragmentType::METHOD:
+      std::tie(p, last) = copy(method, p, last);
+      break;
+    case LogFragmentType::PATH:
+      std::tie(p, last) = copy_escape(path, p, last);
+      break;
+    case LogFragmentType::PATH_WITHOUT_QUERY:
+      std::tie(p, last) = copy_escape(path_without_query, p, last);
+      break;
+    case LogFragmentType::PROTOCOL_VERSION:
+      std::tie(p, last) = copy_l("HTTP/", p, last);
+      std::tie(p, last) = copy(req.http_major, p, last);
+      if (req.http_major < 2) {
+        std::tie(p, last) = copy('.', p, last);
+        std::tie(p, last) = copy(req.http_minor, p, last);
+      }
+      break;
     case LogFragmentType::STATUS:
       std::tie(p, last) = copy(resp.http_status, p, last);
       break;
@@ -735,7 +755,11 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
         std::tie(p, last) = copy('-', p, last);
         break;
       }
+#if OPENSSL_3_0_0_API
+      auto x = SSL_get0_peer_certificate(lgsp.ssl);
+#else  // !OPENSSL_3_0_0_API
       auto x = SSL_get_peer_certificate(lgsp.ssl);
+#endif // !OPENSSL_3_0_0_API
       if (!x) {
         std::tie(p, last) = copy('-', p, last);
         break;
@@ -746,7 +770,9 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
           lf.type == LogFragmentType::TLS_CLIENT_FINGERPRINT_SHA256
               ? EVP_sha256()
               : EVP_sha1());
+#if !OPENSSL_3_0_0_API
       X509_free(x);
+#endif // !OPENSSL_3_0_0_API
       if (len <= 0) {
         std::tie(p, last) = copy('-', p, last);
         break;
@@ -760,7 +786,11 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
         std::tie(p, last) = copy('-', p, last);
         break;
       }
+#if OPENSSL_3_0_0_API
+      auto x = SSL_get0_peer_certificate(lgsp.ssl);
+#else  // !OPENSSL_3_0_0_API
       auto x = SSL_get_peer_certificate(lgsp.ssl);
+#endif // !OPENSSL_3_0_0_API
       if (!x) {
         std::tie(p, last) = copy('-', p, last);
         break;
@@ -768,7 +798,9 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
       auto name = lf.type == LogFragmentType::TLS_CLIENT_ISSUER_NAME
                       ? tls::get_x509_issuer_name(balloc, x)
                       : tls::get_x509_subject_name(balloc, x);
+#if !OPENSSL_3_0_0_API
       X509_free(x);
+#endif // !OPENSSL_3_0_0_API
       if (name.empty()) {
         std::tie(p, last) = copy('-', p, last);
         break;
@@ -781,13 +813,19 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
         std::tie(p, last) = copy('-', p, last);
         break;
       }
+#if OPENSSL_3_0_0_API
+      auto x = SSL_get0_peer_certificate(lgsp.ssl);
+#else  // !OPENSSL_3_0_0_API
       auto x = SSL_get_peer_certificate(lgsp.ssl);
+#endif // !OPENSSL_3_0_0_API
       if (!x) {
         std::tie(p, last) = copy('-', p, last);
         break;
       }
       auto sn = tls::get_x509_serial(balloc, x);
+#if !OPENSSL_3_0_0_API
       X509_free(x);
+#endif // !OPENSSL_3_0_0_API
       if (sn.empty()) {
         std::tie(p, last) = copy('-', p, last);
         break;
@@ -944,7 +982,7 @@ int open_log_file(const char *path) {
       strcmp(path, "/proc/self/fd/2") == 0) {
     return STDERR_COPY;
   }
-#if defined O_CLOEXEC
+#ifdef O_CLOEXEC
 
   auto fd = open(path, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC,
                  S_IRUSR | S_IWUSR | S_IRGRP);
index 7b0b914..81035b2 100644 (file)
@@ -249,6 +249,10 @@ enum class LogFragmentType {
   TLS_CLIENT_SUBJECT_NAME,
   BACKEND_HOST,
   BACKEND_PORT,
+  METHOD,
+  PATH,
+  PATH_WITHOUT_QUERY,
+  PROTOCOL_VERSION,
 };
 
 struct LogFragment {
index 5f9aa67..8d33d82 100644 (file)
@@ -115,7 +115,7 @@ MemcachedConnection::MemcachedConnection(const Address *addr,
       try_count_(0),
       connected_(false) {}
 
-MemcachedConnection::~MemcachedConnection() { disconnect(); }
+MemcachedConnection::~MemcachedConnection() { conn_.disconnect(); }
 
 namespace {
 void clear_request(std::deque<std::unique_ptr<MemcachedRequest>> &q) {
index 15466c0..b5c6ed3 100644 (file)
@@ -75,6 +75,7 @@ int MRubyContext::run_app(Downstream *downstream, int phase) {
     break;
   default:
     assert(0);
+    abort();
   }
 
   auto res = mrb_funcall(mrb_, app_, method, 1, env_);
@@ -117,7 +118,7 @@ namespace {
 mrb_value instantiate_app(mrb_state *mrb, RProc *proc) {
   mrb->ud = nullptr;
 
-  auto res = mrb_run(mrb, proc, mrb_top_self(mrb));
+  auto res = mrb_top_run(mrb, proc, mrb_top_self(mrb), 0);
 
   if (mrb->exc) {
     auto exc = mrb_obj_value(mrb->exc);
index b3ed365..5ebd9c0 100644 (file)
@@ -153,7 +153,11 @@ mrb_value env_get_tls_client_fingerprint_md(mrb_state *mrb, const EVP_MD *md) {
     return mrb_str_new_static(mrb, "", 0);
   }
 
+#if OPENSSL_3_0_0_API
+  auto x = SSL_get0_peer_certificate(ssl);
+#else  // !OPENSSL_3_0_0_API
   auto x = SSL_get_peer_certificate(ssl);
+#endif // !OPENSSL_3_0_0_API
   if (!x) {
     return mrb_str_new_static(mrb, "", 0);
   }
@@ -161,7 +165,9 @@ mrb_value env_get_tls_client_fingerprint_md(mrb_state *mrb, const EVP_MD *md) {
   // Currently the largest hash value is SHA-256, which is 32 bytes.
   std::array<uint8_t, 32> buf;
   auto slen = tls::get_x509_fingerprint(buf.data(), buf.size(), x, md);
+#if !OPENSSL_3_0_0_API
   X509_free(x);
+#endif // !OPENSSL_3_0_0_API
   if (slen == -1) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "could not compute client fingerprint");
   }
@@ -199,14 +205,20 @@ mrb_value env_get_tls_client_subject_name(mrb_state *mrb, mrb_value self) {
     return mrb_str_new_static(mrb, "", 0);
   }
 
+#if OPENSSL_3_0_0_API
+  auto x = SSL_get0_peer_certificate(ssl);
+#else  // !OPENSSL_3_0_0_API
   auto x = SSL_get_peer_certificate(ssl);
+#endif // !OPENSSL_3_0_0_API
   if (!x) {
     return mrb_str_new_static(mrb, "", 0);
   }
 
   auto &balloc = downstream->get_block_allocator();
   auto name = tls::get_x509_subject_name(balloc, x);
+#if !OPENSSL_3_0_0_API
   X509_free(x);
+#endif // !OPENSSL_3_0_0_API
   return mrb_str_new(mrb, name.c_str(), name.size());
 }
 } // namespace
@@ -223,14 +235,20 @@ mrb_value env_get_tls_client_issuer_name(mrb_state *mrb, mrb_value self) {
     return mrb_str_new_static(mrb, "", 0);
   }
 
+#if OPENSSL_3_0_0_API
+  auto x = SSL_get0_peer_certificate(ssl);
+#else  // !OPENSSL_3_0_0_API
   auto x = SSL_get_peer_certificate(ssl);
+#endif // !OPENSSL_3_0_0_API
   if (!x) {
     return mrb_str_new_static(mrb, "", 0);
   }
 
   auto &balloc = downstream->get_block_allocator();
   auto name = tls::get_x509_issuer_name(balloc, x);
+#if !OPENSSL_3_0_0_API
   X509_free(x);
+#endif // !OPENSSL_3_0_0_API
   return mrb_str_new(mrb, name.c_str(), name.size());
 }
 } // namespace
@@ -247,14 +265,20 @@ mrb_value env_get_tls_client_serial(mrb_state *mrb, mrb_value self) {
     return mrb_str_new_static(mrb, "", 0);
   }
 
+#if OPENSSL_3_0_0_API
+  auto x = SSL_get0_peer_certificate(ssl);
+#else  // !OPENSSL_3_0_0_API
   auto x = SSL_get_peer_certificate(ssl);
+#endif // !OPENSSL_3_0_0_API
   if (!x) {
     return mrb_str_new_static(mrb, "", 0);
   }
 
   auto &balloc = downstream->get_block_allocator();
   auto sn = tls::get_x509_serial(balloc, x);
+#if !OPENSSL_3_0_0_API
   X509_free(x);
+#endif // !OPENSSL_3_0_0_API
   return mrb_str_new(mrb, sn.c_str(), sn.size());
 }
 } // namespace
@@ -271,16 +295,24 @@ mrb_value env_get_tls_client_not_before(mrb_state *mrb, mrb_value self) {
     return mrb_fixnum_value(0);
   }
 
+#if OPENSSL_3_0_0_API
+  auto x = SSL_get0_peer_certificate(ssl);
+#else  // !OPENSSL_3_0_0_API
   auto x = SSL_get_peer_certificate(ssl);
+#endif // !OPENSSL_3_0_0_API
   if (!x) {
     return mrb_fixnum_value(0);
   }
 
   time_t t;
   if (tls::get_x509_not_before(t, x) != 0) {
-    return mrb_fixnum_value(0);
+    t = 0;
   }
 
+#if !OPENSSL_3_0_0_API
+  X509_free(x);
+#endif // !OPENSSL_3_0_0_API
+
   return mrb_fixnum_value(t);
 }
 } // namespace
@@ -297,16 +329,24 @@ mrb_value env_get_tls_client_not_after(mrb_state *mrb, mrb_value self) {
     return mrb_fixnum_value(0);
   }
 
+#if OPENSSL_3_0_0_API
+  auto x = SSL_get0_peer_certificate(ssl);
+#else  // !OPENSSL_3_0_0_API
   auto x = SSL_get_peer_certificate(ssl);
+#endif // !OPENSSL_3_0_0_API
   if (!x) {
     return mrb_fixnum_value(0);
   }
 
   time_t t;
   if (tls::get_x509_not_after(t, x) != 0) {
-    return mrb_fixnum_value(0);
+    t = 0;
   }
 
+#if !OPENSSL_3_0_0_API
+  X509_free(x);
+#endif // !OPENSSL_3_0_0_API
+
   return mrb_fixnum_value(t);
 }
 } // namespace
diff --git a/src/shrpx_null_downstream_connection.cc b/src/shrpx_null_downstream_connection.cc
new file mode 100644 (file)
index 0000000..3a80b30
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "shrpx_null_downstream_connection.h"
+#include "shrpx_upstream.h"
+#include "shrpx_downstream.h"
+#include "shrpx_log.h"
+
+namespace shrpx {
+
+NullDownstreamConnection::NullDownstreamConnection(
+    const std::shared_ptr<DownstreamAddrGroup> &group)
+    : group_(group) {}
+
+NullDownstreamConnection::~NullDownstreamConnection() {}
+
+int NullDownstreamConnection::attach_downstream(Downstream *downstream) {
+  if (LOG_ENABLED(INFO)) {
+    DCLOG(INFO, this) << "Attaching to DOWNSTREAM:" << downstream;
+  }
+
+  downstream_ = downstream;
+
+  return 0;
+}
+
+void NullDownstreamConnection::detach_downstream(Downstream *downstream) {
+  if (LOG_ENABLED(INFO)) {
+    DCLOG(INFO, this) << "Detaching from DOWNSTREAM:" << downstream;
+  }
+  downstream_ = nullptr;
+}
+
+int NullDownstreamConnection::push_request_headers() { return 0; }
+
+int NullDownstreamConnection::push_upload_data_chunk(const uint8_t *data,
+                                                     size_t datalen) {
+  return 0;
+}
+
+int NullDownstreamConnection::end_upload_data() { return 0; }
+
+void NullDownstreamConnection::pause_read(IOCtrlReason reason) {}
+
+int NullDownstreamConnection::resume_read(IOCtrlReason reason,
+                                          size_t consumed) {
+  return 0;
+}
+
+void NullDownstreamConnection::force_resume_read() {}
+
+int NullDownstreamConnection::on_read() { return 0; }
+
+int NullDownstreamConnection::on_write() { return 0; }
+
+void NullDownstreamConnection::on_upstream_change(Upstream *uptream) {}
+
+bool NullDownstreamConnection::poolable() const { return false; }
+
+const std::shared_ptr<DownstreamAddrGroup> &
+NullDownstreamConnection::get_downstream_addr_group() const {
+  return group_;
+}
+
+DownstreamAddr *NullDownstreamConnection::get_addr() const { return nullptr; }
+
+} // namespace shrpx
diff --git a/src/shrpx_null_downstream_connection.h b/src/shrpx_null_downstream_connection.h
new file mode 100644 (file)
index 0000000..829d659
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef SHRPX_NULL_DOWNSTREAM_CONNECTION_H
+#define SHRPX_NULL_DOWNSTREAM_CONNECTION_H
+
+#include "shrpx_downstream_connection.h"
+#include "template.h"
+
+using namespace nghttp2;
+
+namespace shrpx {
+
+class NullDownstreamConnection : public DownstreamConnection {
+public:
+  NullDownstreamConnection(const std::shared_ptr<DownstreamAddrGroup> &group);
+  virtual ~NullDownstreamConnection();
+  virtual int attach_downstream(Downstream *downstream);
+  virtual void detach_downstream(Downstream *downstream);
+
+  virtual int push_request_headers();
+  virtual int push_upload_data_chunk(const uint8_t *data, size_t datalen);
+  virtual int end_upload_data();
+
+  virtual void pause_read(IOCtrlReason reason);
+  virtual int resume_read(IOCtrlReason reason, size_t consumed);
+  virtual void force_resume_read();
+
+  virtual int on_read();
+  virtual int on_write();
+
+  virtual void on_upstream_change(Upstream *uptream);
+
+  // true if this object is poolable.
+  virtual bool poolable() const;
+
+  virtual const std::shared_ptr<DownstreamAddrGroup> &
+  get_downstream_addr_group() const;
+  virtual DownstreamAddr *get_addr() const;
+
+private:
+  std::shared_ptr<DownstreamAddrGroup> group_;
+};
+
+} // namespace shrpx
+
+#endif // SHRPX_NULL_DOWNSTREAM_CONNECTION_H
diff --git a/src/shrpx_quic.cc b/src/shrpx_quic.cc
new file mode 100644 (file)
index 0000000..224fbbb
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "shrpx_quic.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/udp.h>
+
+#include <array>
+#include <chrono>
+
+#include <ngtcp2/ngtcp2_crypto.h>
+
+#include <nghttp3/nghttp3.h>
+
+#include <openssl/rand.h>
+
+#include "shrpx_config.h"
+#include "shrpx_log.h"
+#include "util.h"
+#include "xsi_strerror.h"
+
+bool operator==(const ngtcp2_cid &lhs, const ngtcp2_cid &rhs) {
+  return ngtcp2_cid_eq(&lhs, &rhs);
+}
+
+namespace shrpx {
+
+ngtcp2_tstamp quic_timestamp() {
+  return std::chrono::duration_cast<std::chrono::nanoseconds>(
+             std::chrono::steady_clock::now().time_since_epoch())
+      .count();
+}
+
+int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
+                     size_t remote_salen, const sockaddr *local_sa,
+                     size_t local_salen, const uint8_t *data, size_t datalen,
+                     size_t gso_size) {
+  iovec msg_iov = {const_cast<uint8_t *>(data), datalen};
+  msghdr msg{};
+  msg.msg_name = const_cast<sockaddr *>(remote_sa);
+  msg.msg_namelen = remote_salen;
+  msg.msg_iov = &msg_iov;
+  msg.msg_iovlen = 1;
+
+  uint8_t msg_ctrl[
+#ifdef UDP_SEGMENT
+      CMSG_SPACE(sizeof(uint16_t)) +
+#endif // UDP_SEGMENT
+      CMSG_SPACE(sizeof(in6_pktinfo))];
+
+  memset(msg_ctrl, 0, sizeof(msg_ctrl));
+
+  msg.msg_control = msg_ctrl;
+  msg.msg_controllen = sizeof(msg_ctrl);
+
+  size_t controllen = 0;
+
+  auto cm = CMSG_FIRSTHDR(&msg);
+
+  switch (local_sa->sa_family) {
+  case AF_INET: {
+    controllen += CMSG_SPACE(sizeof(in_pktinfo));
+    cm->cmsg_level = IPPROTO_IP;
+    cm->cmsg_type = IP_PKTINFO;
+    cm->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
+    auto pktinfo = reinterpret_cast<in_pktinfo *>(CMSG_DATA(cm));
+    memset(pktinfo, 0, sizeof(in_pktinfo));
+    auto addrin =
+        reinterpret_cast<sockaddr_in *>(const_cast<sockaddr *>(local_sa));
+    pktinfo->ipi_spec_dst = addrin->sin_addr;
+    break;
+  }
+  case AF_INET6: {
+    controllen += CMSG_SPACE(sizeof(in6_pktinfo));
+    cm->cmsg_level = IPPROTO_IPV6;
+    cm->cmsg_type = IPV6_PKTINFO;
+    cm->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
+    auto pktinfo = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cm));
+    memset(pktinfo, 0, sizeof(in6_pktinfo));
+    auto addrin =
+        reinterpret_cast<sockaddr_in6 *>(const_cast<sockaddr *>(local_sa));
+    pktinfo->ipi6_addr = addrin->sin6_addr;
+    break;
+  }
+  default:
+    assert(0);
+  }
+
+#ifdef UDP_SEGMENT
+  if (gso_size && datalen > gso_size) {
+    controllen += CMSG_SPACE(sizeof(uint16_t));
+    cm = CMSG_NXTHDR(&msg, cm);
+    cm->cmsg_level = SOL_UDP;
+    cm->cmsg_type = UDP_SEGMENT;
+    cm->cmsg_len = CMSG_LEN(sizeof(uint16_t));
+    *(reinterpret_cast<uint16_t *>(CMSG_DATA(cm))) = gso_size;
+  }
+#endif // UDP_SEGMENT
+
+  msg.msg_controllen = controllen;
+
+  ssize_t nwrite;
+
+  do {
+    nwrite = sendmsg(faddr->fd, &msg, 0);
+  } while (nwrite == -1 && errno == EINTR);
+
+  if (nwrite == -1) {
+    if (LOG_ENABLED(INFO)) {
+      auto error = errno;
+      LOG(INFO) << "sendmsg failed: errno=" << error;
+    }
+
+    return -errno;
+  }
+
+  if (LOG_ENABLED(INFO)) {
+    LOG(INFO) << "QUIC sent packet: local="
+              << util::to_numeric_addr(local_sa, local_salen)
+              << " remote=" << util::to_numeric_addr(remote_sa, remote_salen)
+              << " " << nwrite << " bytes";
+  }
+
+  return 0;
+}
+
+int generate_quic_retry_connection_id(ngtcp2_cid &cid, size_t cidlen,
+                                      const uint8_t *server_id, uint8_t km_id,
+                                      const uint8_t *key) {
+  assert(cidlen == SHRPX_QUIC_SCIDLEN);
+
+  if (RAND_bytes(cid.data, cidlen) != 1) {
+    return -1;
+  }
+
+  cid.datalen = cidlen;
+
+  cid.data[0] = (cid.data[0] & 0x3f) | km_id;
+
+  auto p = cid.data + SHRPX_QUIC_CID_PREFIX_OFFSET;
+
+  std::copy_n(server_id, SHRPX_QUIC_SERVER_IDLEN, p);
+
+  return encrypt_quic_connection_id(p, p, key);
+}
+
+int generate_quic_connection_id(ngtcp2_cid &cid, size_t cidlen,
+                                const uint8_t *cid_prefix, uint8_t km_id,
+                                const uint8_t *key) {
+  assert(cidlen == SHRPX_QUIC_SCIDLEN);
+
+  if (RAND_bytes(cid.data, cidlen) != 1) {
+    return -1;
+  }
+
+  cid.datalen = cidlen;
+
+  cid.data[0] = (cid.data[0] & 0x3f) | km_id;
+
+  auto p = cid.data + SHRPX_QUIC_CID_PREFIX_OFFSET;
+
+  std::copy_n(cid_prefix, SHRPX_QUIC_CID_PREFIXLEN, p);
+
+  return encrypt_quic_connection_id(p, p, key);
+}
+
+int encrypt_quic_connection_id(uint8_t *dest, const uint8_t *src,
+                               const uint8_t *key) {
+  auto ctx = EVP_CIPHER_CTX_new();
+  auto d = defer(EVP_CIPHER_CTX_free, ctx);
+
+  if (!EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), nullptr, key, nullptr)) {
+    return -1;
+  }
+
+  EVP_CIPHER_CTX_set_padding(ctx, 0);
+
+  int len;
+
+  if (!EVP_EncryptUpdate(ctx, dest, &len, src, SHRPX_QUIC_DECRYPTED_DCIDLEN) ||
+      !EVP_EncryptFinal_ex(ctx, dest + len, &len)) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int decrypt_quic_connection_id(uint8_t *dest, const uint8_t *src,
+                               const uint8_t *key) {
+  auto ctx = EVP_CIPHER_CTX_new();
+  auto d = defer(EVP_CIPHER_CTX_free, ctx);
+
+  if (!EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), nullptr, key, nullptr)) {
+    return -1;
+  }
+
+  EVP_CIPHER_CTX_set_padding(ctx, 0);
+
+  int len;
+
+  if (!EVP_DecryptUpdate(ctx, dest, &len, src, SHRPX_QUIC_DECRYPTED_DCIDLEN) ||
+      !EVP_DecryptFinal_ex(ctx, dest + len, &len)) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int generate_quic_hashed_connection_id(ngtcp2_cid &dest,
+                                       const Address &remote_addr,
+                                       const Address &local_addr,
+                                       const ngtcp2_cid &cid) {
+  auto ctx = EVP_MD_CTX_new();
+  auto d = defer(EVP_MD_CTX_free, ctx);
+
+  std::array<uint8_t, 32> h;
+  unsigned int hlen = EVP_MD_size(EVP_sha256());
+
+  if (!EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr) ||
+      !EVP_DigestUpdate(ctx, &remote_addr.su.sa, remote_addr.len) ||
+      !EVP_DigestUpdate(ctx, &local_addr.su.sa, local_addr.len) ||
+      !EVP_DigestUpdate(ctx, cid.data, cid.datalen) ||
+      !EVP_DigestFinal_ex(ctx, h.data(), &hlen)) {
+    return -1;
+  }
+
+  assert(hlen == h.size());
+
+  std::copy_n(std::begin(h), sizeof(dest.data), std::begin(dest.data));
+  dest.datalen = sizeof(dest.data);
+
+  return 0;
+}
+
+int generate_quic_stateless_reset_token(uint8_t *token, const ngtcp2_cid &cid,
+                                        const uint8_t *secret,
+                                        size_t secretlen) {
+  if (ngtcp2_crypto_generate_stateless_reset_token(token, secret, secretlen,
+                                                   &cid) != 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int generate_retry_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa,
+                         socklen_t salen, const ngtcp2_cid &retry_scid,
+                         const ngtcp2_cid &odcid, const uint8_t *secret,
+                         size_t secretlen) {
+  auto t = std::chrono::duration_cast<std::chrono::nanoseconds>(
+               std::chrono::system_clock::now().time_since_epoch())
+               .count();
+
+  auto stokenlen = ngtcp2_crypto_generate_retry_token(
+      token, secret, secretlen, sa, salen, &retry_scid, &odcid, t);
+  if (stokenlen < 0) {
+    return -1;
+  }
+
+  tokenlen = stokenlen;
+
+  return 0;
+}
+
+int verify_retry_token(ngtcp2_cid &odcid, const uint8_t *token, size_t tokenlen,
+                       const ngtcp2_cid &dcid, const sockaddr *sa,
+                       socklen_t salen, const uint8_t *secret,
+                       size_t secretlen) {
+
+  auto t = std::chrono::duration_cast<std::chrono::nanoseconds>(
+               std::chrono::system_clock::now().time_since_epoch())
+               .count();
+
+  if (ngtcp2_crypto_verify_retry_token(&odcid, token, tokenlen, secret,
+                                       secretlen, sa, salen, &dcid,
+                                       10 * NGTCP2_SECONDS, t) != 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int generate_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa,
+                   size_t salen, const uint8_t *secret, size_t secretlen) {
+  auto t = std::chrono::duration_cast<std::chrono::nanoseconds>(
+               std::chrono::system_clock::now().time_since_epoch())
+               .count();
+
+  auto stokenlen = ngtcp2_crypto_generate_regular_token(
+      token, secret, secretlen, sa, salen, t);
+  if (stokenlen < 0) {
+    return -1;
+  }
+
+  tokenlen = stokenlen;
+
+  return 0;
+}
+
+int verify_token(const uint8_t *token, size_t tokenlen, const sockaddr *sa,
+                 socklen_t salen, const uint8_t *secret, size_t secretlen) {
+  auto t = std::chrono::duration_cast<std::chrono::nanoseconds>(
+               std::chrono::system_clock::now().time_since_epoch())
+               .count();
+
+  if (ngtcp2_crypto_verify_regular_token(token, tokenlen, secret, secretlen, sa,
+                                         salen, 3600 * NGTCP2_SECONDS,
+                                         t) != 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int generate_quic_connection_id_encryption_key(uint8_t *key, size_t keylen,
+                                               const uint8_t *secret,
+                                               size_t secretlen,
+                                               const uint8_t *salt,
+                                               size_t saltlen) {
+  constexpr uint8_t info[] = "connection id encryption key";
+  ngtcp2_crypto_md sha256;
+  ngtcp2_crypto_md_init(
+      &sha256, reinterpret_cast<void *>(const_cast<EVP_MD *>(EVP_sha256())));
+
+  if (ngtcp2_crypto_hkdf(key, keylen, &sha256, secret, secretlen, salt, saltlen,
+                         info, str_size(info)) != 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+const QUICKeyingMaterial *
+select_quic_keying_material(const QUICKeyingMaterials &qkms,
+                            const uint8_t *cid) {
+  for (auto &qkm : qkms.keying_materials) {
+    if (((*cid) & 0xc0) == qkm.id) {
+      return &qkm;
+    }
+  }
+
+  return &qkms.keying_materials.front();
+}
+
+} // namespace shrpx
diff --git a/src/shrpx_quic.h b/src/shrpx_quic.h
new file mode 100644 (file)
index 0000000..8f40025
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef SHRPX_QUIC_H
+#define SHRPX_QUIC_H
+
+#include "shrpx.h"
+
+#include <stdint.h>
+
+#include <functional>
+
+#include <ngtcp2/ngtcp2.h>
+
+#include "network.h"
+
+using namespace nghttp2;
+
+namespace std {
+template <> struct hash<ngtcp2_cid> {
+  std::size_t operator()(const ngtcp2_cid &cid) const noexcept {
+    // FNV-1a 64bits variant
+    constexpr uint64_t basis = 0xCBF29CE484222325ULL;
+    const uint8_t *p = cid.data, *end = cid.data + cid.datalen;
+    uint64_t h = basis;
+
+    for (; p != end;) {
+      h ^= *p++;
+      h *= basis;
+    }
+
+    return static_cast<size_t>(h);
+  }
+};
+} // namespace std
+
+bool operator==(const ngtcp2_cid &lhs, const ngtcp2_cid &rhs);
+
+namespace shrpx {
+
+struct UpstreamAddr;
+struct QUICKeyingMaterials;
+struct QUICKeyingMaterial;
+
+constexpr size_t SHRPX_QUIC_SCIDLEN = 20;
+constexpr size_t SHRPX_QUIC_SERVER_IDLEN = 4;
+// SHRPX_QUIC_CID_PREFIXLEN includes SHRPX_QUIC_SERVER_IDLEN.
+constexpr size_t SHRPX_QUIC_CID_PREFIXLEN = 8;
+constexpr size_t SHRPX_QUIC_CID_PREFIX_OFFSET = 1;
+constexpr size_t SHRPX_QUIC_DECRYPTED_DCIDLEN = 16;
+constexpr size_t SHRPX_QUIC_CID_ENCRYPTION_KEYLEN = 16;
+constexpr size_t SHRPX_QUIC_MAX_UDP_PAYLOAD_SIZE = 1472;
+constexpr size_t SHRPX_QUIC_CONN_CLOSE_PKTLEN = 256;
+constexpr size_t SHRPX_QUIC_STATELESS_RESET_BURST = 100;
+constexpr size_t SHRPX_QUIC_SECRET_RESERVEDLEN = 4;
+constexpr size_t SHRPX_QUIC_SECRETLEN = 32;
+constexpr size_t SHRPX_QUIC_SALTLEN = 32;
+
+ngtcp2_tstamp quic_timestamp();
+
+int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
+                     size_t remote_salen, const sockaddr *local_sa,
+                     size_t local_salen, const uint8_t *data, size_t datalen,
+                     size_t gso_size);
+
+int generate_quic_retry_connection_id(ngtcp2_cid &cid, size_t cidlen,
+                                      const uint8_t *server_id, uint8_t km_id,
+                                      const uint8_t *key);
+
+int generate_quic_connection_id(ngtcp2_cid &cid, size_t cidlen,
+                                const uint8_t *cid_prefix, uint8_t km_id,
+                                const uint8_t *key);
+
+int encrypt_quic_connection_id(uint8_t *dest, const uint8_t *src,
+                               const uint8_t *key);
+
+int decrypt_quic_connection_id(uint8_t *dest, const uint8_t *src,
+                               const uint8_t *key);
+
+int generate_quic_hashed_connection_id(ngtcp2_cid &dest,
+                                       const Address &remote_addr,
+                                       const Address &local_addr,
+                                       const ngtcp2_cid &cid);
+
+int generate_quic_stateless_reset_token(uint8_t *token, const ngtcp2_cid &cid,
+                                        const uint8_t *secret,
+                                        size_t secretlen);
+
+int generate_retry_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa,
+                         socklen_t salen, const ngtcp2_cid &retry_scid,
+                         const ngtcp2_cid &odcid, const uint8_t *secret,
+                         size_t secretlen);
+
+int verify_retry_token(ngtcp2_cid &odcid, const uint8_t *token, size_t tokenlen,
+                       const ngtcp2_cid &dcid, const sockaddr *sa,
+                       socklen_t salen, const uint8_t *secret,
+                       size_t secretlen);
+
+int generate_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa,
+                   size_t salen, const uint8_t *secret, size_t secretlen);
+
+int verify_token(const uint8_t *token, size_t tokenlen, const sockaddr *sa,
+                 socklen_t salen, const uint8_t *secret, size_t secretlen);
+
+int generate_quic_connection_id_encryption_key(uint8_t *key, size_t keylen,
+                                               const uint8_t *secret,
+                                               size_t secretlen,
+                                               const uint8_t *salt,
+                                               size_t saltlen);
+
+const QUICKeyingMaterial *
+select_quic_keying_material(const QUICKeyingMaterials &qkms,
+                            const uint8_t *cid);
+
+} // namespace shrpx
+
+#endif // SHRPX_QUIC_H
diff --git a/src/shrpx_quic_connection_handler.cc b/src/shrpx_quic_connection_handler.cc
new file mode 100644 (file)
index 0000000..325e695
--- /dev/null
@@ -0,0 +1,737 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "shrpx_quic_connection_handler.h"
+
+#include <openssl/rand.h>
+
+#include <ngtcp2/ngtcp2.h>
+#include <ngtcp2/ngtcp2_crypto.h>
+
+#include "shrpx_worker.h"
+#include "shrpx_client_handler.h"
+#include "shrpx_log.h"
+#include "shrpx_http3_upstream.h"
+#include "shrpx_connection_handler.h"
+
+namespace shrpx {
+
+namespace {
+void stateless_reset_bucket_regen_timercb(struct ev_loop *loop, ev_timer *w,
+                                          int revents) {
+  auto quic_conn_handler = static_cast<QUICConnectionHandler *>(w->data);
+
+  quic_conn_handler->on_stateless_reset_bucket_regen();
+}
+} // namespace
+
+QUICConnectionHandler::QUICConnectionHandler(Worker *worker)
+    : worker_{worker},
+      stateless_reset_bucket_{SHRPX_QUIC_STATELESS_RESET_BURST} {
+  ev_timer_init(&stateless_reset_bucket_regen_timer_,
+                stateless_reset_bucket_regen_timercb, 0., 1.);
+  stateless_reset_bucket_regen_timer_.data = this;
+}
+
+QUICConnectionHandler::~QUICConnectionHandler() {
+  ev_timer_stop(worker_->get_loop(), &stateless_reset_bucket_regen_timer_);
+}
+
+int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr,
+                                         const Address &remote_addr,
+                                         const Address &local_addr,
+                                         const uint8_t *data, size_t datalen) {
+  int rv;
+  uint32_t version;
+  const uint8_t *dcid, *scid;
+  size_t dcidlen, scidlen;
+
+  rv = ngtcp2_pkt_decode_version_cid(&version, &dcid, &dcidlen, &scid, &scidlen,
+                                     data, datalen, SHRPX_QUIC_SCIDLEN);
+  switch (rv) {
+  case 0:
+    break;
+  case NGTCP2_ERR_VERSION_NEGOTIATION:
+    send_version_negotiation(faddr, version, dcid, dcidlen, scid, scidlen,
+                             remote_addr, local_addr);
+
+    return 0;
+  default:
+    return 0;
+  }
+
+  auto config = get_config();
+
+  ngtcp2_cid dcid_key;
+  ngtcp2_cid_init(&dcid_key, dcid, dcidlen);
+
+  auto conn_handler = worker_->get_connection_handler();
+
+  ClientHandler *handler;
+
+  auto &quicconf = config->quic;
+
+  auto it = connections_.find(dcid_key);
+  if (it == std::end(connections_)) {
+    auto cwit = close_waits_.find(dcid_key);
+    if (cwit != std::end(close_waits_)) {
+      auto cw = (*cwit).second;
+
+      cw->handle_packet(faddr, remote_addr, local_addr, data, datalen);
+
+      return 0;
+    }
+
+    if (data[0] & 0x80) {
+      if (generate_quic_hashed_connection_id(dcid_key, remote_addr, local_addr,
+                                             dcid_key) != 0) {
+        return 0;
+      }
+
+      it = connections_.find(dcid_key);
+      if (it == std::end(connections_)) {
+        auto cwit = close_waits_.find(dcid_key);
+        if (cwit != std::end(close_waits_)) {
+          auto cw = (*cwit).second;
+
+          cw->handle_packet(faddr, remote_addr, local_addr, data, datalen);
+
+          return 0;
+        }
+      }
+    }
+  }
+
+  if (it == std::end(connections_)) {
+    std::array<uint8_t, SHRPX_QUIC_DECRYPTED_DCIDLEN> decrypted_dcid;
+
+    auto &qkms = conn_handler->get_quic_keying_materials();
+    const QUICKeyingMaterial *qkm = nullptr;
+
+    if (dcidlen == SHRPX_QUIC_SCIDLEN) {
+      qkm = select_quic_keying_material(*qkms.get(), dcid);
+
+      if (decrypt_quic_connection_id(decrypted_dcid.data(),
+                                     dcid + SHRPX_QUIC_CID_PREFIX_OFFSET,
+                                     qkm->cid_encryption_key.data()) != 0) {
+        return 0;
+      }
+
+      if (qkm != &qkms->keying_materials.front() ||
+          !std::equal(std::begin(decrypted_dcid),
+                      std::begin(decrypted_dcid) + SHRPX_QUIC_CID_PREFIXLEN,
+                      worker_->get_cid_prefix())) {
+        auto quic_lwp =
+            conn_handler->match_quic_lingering_worker_process_cid_prefix(
+                decrypted_dcid.data(), decrypted_dcid.size());
+        if (quic_lwp) {
+          if (conn_handler->forward_quic_packet_to_lingering_worker_process(
+                  quic_lwp, remote_addr, local_addr, data, datalen) == 0) {
+            return 0;
+          }
+
+          return 0;
+        }
+      }
+    }
+
+    // new connection
+
+    auto &upstreamconf = config->conn.upstream;
+    if (worker_->get_worker_stat()->num_connections >=
+        upstreamconf.worker_connections) {
+      if (LOG_ENABLED(INFO)) {
+        LOG(INFO) << "Too many connections >="
+                  << upstreamconf.worker_connections;
+      }
+
+      return 0;
+    }
+
+    ngtcp2_pkt_hd hd;
+    ngtcp2_cid odcid, *podcid = nullptr;
+    const uint8_t *token = nullptr;
+    size_t tokenlen = 0;
+
+    switch (ngtcp2_accept(&hd, data, datalen)) {
+    case 0: {
+      // If we get Initial and it has the CID prefix of this worker,
+      // it is likely that client is intentionally use the prefix.
+      // Just drop it.
+      if (dcidlen == SHRPX_QUIC_SCIDLEN) {
+        if (qkm != &qkms->keying_materials.front()) {
+          qkm = &qkms->keying_materials.front();
+
+          if (decrypt_quic_connection_id(decrypted_dcid.data(),
+                                         dcid + SHRPX_QUIC_CID_PREFIX_OFFSET,
+                                         qkm->cid_encryption_key.data()) != 0) {
+            return 0;
+          }
+        }
+
+        if (std::equal(std::begin(decrypted_dcid),
+                       std::begin(decrypted_dcid) + SHRPX_QUIC_CID_PREFIXLEN,
+                       worker_->get_cid_prefix())) {
+          return 0;
+        }
+      }
+
+      if (worker_->get_graceful_shutdown()) {
+        send_connection_close(faddr, version, hd.dcid, hd.scid, remote_addr,
+                              local_addr, NGTCP2_CONNECTION_REFUSED);
+        return 0;
+      }
+
+      if (hd.token.len == 0) {
+        if (quicconf.upstream.require_token) {
+          send_retry(faddr, version, dcid, dcidlen, scid, scidlen, remote_addr,
+                     local_addr);
+
+          return 0;
+        }
+
+        break;
+      }
+
+      if (dcidlen != SHRPX_QUIC_SCIDLEN) {
+        // Initial packets with token must have DCID chosen by server.
+        return 0;
+      }
+
+      auto qkm = select_quic_keying_material(*qkms.get(), dcid);
+
+      switch (hd.token.base[0]) {
+      case NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY:
+        if (verify_retry_token(odcid, hd.token.base, hd.token.len, hd.dcid,
+                               &remote_addr.su.sa, remote_addr.len,
+                               qkm->secret.data(), qkm->secret.size()) != 0) {
+          if (LOG_ENABLED(INFO)) {
+            LOG(INFO) << "Failed to validate Retry token from remote="
+                      << util::to_numeric_addr(&remote_addr);
+          }
+
+          // 2nd Retry packet is not allowed, so send CONNECTION_CLOSE
+          // with INVALID_TOKEN.
+          send_connection_close(faddr, version, hd.dcid, hd.scid, remote_addr,
+                                local_addr, NGTCP2_INVALID_TOKEN);
+          return 0;
+        }
+
+        if (LOG_ENABLED(INFO)) {
+          LOG(INFO) << "Successfully validated Retry token from remote="
+                    << util::to_numeric_addr(&remote_addr);
+        }
+
+        podcid = &odcid;
+        token = hd.token.base;
+        tokenlen = hd.token.len;
+
+        break;
+      case NGTCP2_CRYPTO_TOKEN_MAGIC_REGULAR:
+        if (verify_token(hd.token.base, hd.token.len, &remote_addr.su.sa,
+                         remote_addr.len, qkm->secret.data(),
+                         qkm->secret.size()) != 0) {
+          if (LOG_ENABLED(INFO)) {
+            LOG(INFO) << "Failed to validate token from remote="
+                      << util::to_numeric_addr(&remote_addr);
+          }
+
+          if (quicconf.upstream.require_token) {
+            send_retry(faddr, version, dcid, dcidlen, scid, scidlen,
+                       remote_addr, local_addr);
+
+            return 0;
+          }
+
+          break;
+        }
+
+        if (LOG_ENABLED(INFO)) {
+          LOG(INFO) << "Successfully validated token from remote="
+                    << util::to_numeric_addr(&remote_addr);
+        }
+
+        token = hd.token.base;
+        tokenlen = hd.token.len;
+
+        break;
+      default:
+        if (quicconf.upstream.require_token) {
+          send_retry(faddr, version, dcid, dcidlen, scid, scidlen, remote_addr,
+                     local_addr);
+
+          return 0;
+        }
+
+        break;
+      }
+
+      break;
+    }
+    case NGTCP2_ERR_RETRY:
+      if (worker_->get_graceful_shutdown()) {
+        send_connection_close(faddr, version, hd.dcid, hd.scid, remote_addr,
+                              local_addr, NGTCP2_CONNECTION_REFUSED);
+        return 0;
+      }
+
+      send_retry(faddr, version, dcid, dcidlen, scid, scidlen, remote_addr,
+                 local_addr);
+      return 0;
+    case NGTCP2_ERR_VERSION_NEGOTIATION:
+      send_version_negotiation(faddr, version, dcid, dcidlen, scid, scidlen,
+                               remote_addr, local_addr);
+      return 0;
+    default:
+      if (!config->single_thread && !(data[0] & 0x80) &&
+          dcidlen == SHRPX_QUIC_SCIDLEN &&
+          !std::equal(std::begin(decrypted_dcid),
+                      std::begin(decrypted_dcid) + SHRPX_QUIC_CID_PREFIXLEN,
+                      worker_->get_cid_prefix())) {
+        if (conn_handler->forward_quic_packet(faddr, remote_addr, local_addr,
+                                              decrypted_dcid.data(), data,
+                                              datalen) == 0) {
+          return 0;
+        }
+      }
+
+      if (!(data[0] & 0x80)) {
+        // TODO Must be rate limited
+        send_stateless_reset(faddr, dcid, dcidlen, remote_addr, local_addr);
+      }
+
+      return 0;
+    }
+
+    handler = handle_new_connection(faddr, remote_addr, local_addr, hd, podcid,
+                                    token, tokenlen);
+    if (handler == nullptr) {
+      return 0;
+    }
+  } else {
+    handler = (*it).second;
+  }
+
+  if (handler->read_quic(faddr, remote_addr, local_addr, data, datalen) != 0) {
+    delete handler;
+    return 0;
+  }
+
+  handler->signal_write();
+
+  return 0;
+}
+
+ClientHandler *QUICConnectionHandler::handle_new_connection(
+    const UpstreamAddr *faddr, const Address &remote_addr,
+    const Address &local_addr, const ngtcp2_pkt_hd &hd, const ngtcp2_cid *odcid,
+    const uint8_t *token, size_t tokenlen) {
+  std::array<char, NI_MAXHOST> host;
+  std::array<char, NI_MAXSERV> service;
+  int rv;
+
+  rv = getnameinfo(&remote_addr.su.sa, remote_addr.len, host.data(),
+                   host.size(), service.data(), service.size(),
+                   NI_NUMERICHOST | NI_NUMERICSERV);
+  if (rv != 0) {
+    LOG(ERROR) << "getnameinfo() failed: " << gai_strerror(rv);
+
+    return nullptr;
+  }
+
+  auto ssl_ctx = worker_->get_quic_sv_ssl_ctx();
+
+  assert(ssl_ctx);
+
+  auto ssl = tls::create_ssl(ssl_ctx);
+  if (ssl == nullptr) {
+    return nullptr;
+  }
+
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+  assert(SSL_is_quic(ssl));
+#endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+
+  SSL_set_accept_state(ssl);
+
+  auto config = get_config();
+  auto &quicconf = config->quic;
+
+  if (quicconf.upstream.early_data) {
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+    SSL_set_quic_early_data_enabled(ssl, 1);
+#else  // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
+    SSL_set_early_data_enabled(ssl, 1);
+#endif // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
+  }
+
+  // Disable TLS session ticket if we don't have working ticket
+  // keys.
+  if (!worker_->get_ticket_keys()) {
+    SSL_set_options(ssl, SSL_OP_NO_TICKET);
+  }
+
+  auto handler = std::make_unique<ClientHandler>(
+      worker_, faddr->fd, ssl, StringRef{host.data()},
+      StringRef{service.data()}, remote_addr.su.sa.sa_family, faddr);
+
+  auto upstream = std::make_unique<Http3Upstream>(handler.get());
+  if (upstream->init(faddr, remote_addr, local_addr, hd, odcid, token,
+                     tokenlen) != 0) {
+    return nullptr;
+  }
+
+  handler->setup_http3_upstream(std::move(upstream));
+
+  return handler.release();
+}
+
+namespace {
+uint32_t generate_reserved_version(const Address &addr, uint32_t version) {
+  uint32_t h = 0x811C9DC5u;
+  const uint8_t *p = reinterpret_cast<const uint8_t *>(&addr.su.sa);
+  const uint8_t *ep = p + addr.len;
+
+  for (; p != ep; ++p) {
+    h ^= *p;
+    h *= 0x01000193u;
+  }
+
+  version = htonl(version);
+  p = (const uint8_t *)&version;
+  ep = p + sizeof(version);
+
+  for (; p != ep; ++p) {
+    h ^= *p;
+    h *= 0x01000193u;
+  }
+
+  h &= 0xf0f0f0f0u;
+  h |= 0x0a0a0a0au;
+
+  return h;
+}
+} // namespace
+
+int QUICConnectionHandler::send_retry(
+    const UpstreamAddr *faddr, uint32_t version, const uint8_t *ini_dcid,
+    size_t ini_dcidlen, const uint8_t *ini_scid, size_t ini_scidlen,
+    const Address &remote_addr, const Address &local_addr) {
+  std::array<char, NI_MAXHOST> host;
+  std::array<char, NI_MAXSERV> port;
+
+  if (getnameinfo(&remote_addr.su.sa, remote_addr.len, host.data(), host.size(),
+                  port.data(), port.size(),
+                  NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
+    return -1;
+  }
+
+  auto config = get_config();
+  auto &quicconf = config->quic;
+
+  auto conn_handler = worker_->get_connection_handler();
+  auto &qkms = conn_handler->get_quic_keying_materials();
+  auto &qkm = qkms->keying_materials.front();
+
+  ngtcp2_cid retry_scid;
+
+  if (generate_quic_retry_connection_id(retry_scid, SHRPX_QUIC_SCIDLEN,
+                                        quicconf.server_id.data(), qkm.id,
+                                        qkm.cid_encryption_key.data()) != 0) {
+    return -1;
+  }
+
+  std::array<uint8_t, NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN> token;
+  size_t tokenlen;
+
+  ngtcp2_cid idcid, iscid;
+  ngtcp2_cid_init(&idcid, ini_dcid, ini_dcidlen);
+  ngtcp2_cid_init(&iscid, ini_scid, ini_scidlen);
+
+  if (generate_retry_token(token.data(), tokenlen, &remote_addr.su.sa,
+                           remote_addr.len, retry_scid, idcid,
+                           qkm.secret.data(), qkm.secret.size()) != 0) {
+    return -1;
+  }
+
+  std::vector<uint8_t> buf;
+  buf.resize(256);
+
+  auto nwrite =
+      ngtcp2_crypto_write_retry(buf.data(), buf.size(), version, &iscid,
+                                &retry_scid, &idcid, token.data(), tokenlen);
+  if (nwrite < 0) {
+    LOG(ERROR) << "ngtcp2_crypto_write_retry: " << ngtcp2_strerror(nwrite);
+    return -1;
+  }
+
+  buf.resize(nwrite);
+
+  quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
+                   &local_addr.su.sa, local_addr.len, buf.data(), buf.size(),
+                   0);
+
+  if (generate_quic_hashed_connection_id(idcid, remote_addr, local_addr,
+                                         idcid) != 0) {
+    return -1;
+  }
+
+  auto d =
+      static_cast<ev_tstamp>(NGTCP2_DEFAULT_INITIAL_RTT * 3) / NGTCP2_SECONDS;
+
+  if (LOG_ENABLED(INFO)) {
+    LOG(INFO) << "Enter close-wait period " << d << "s with " << buf.size()
+              << " bytes sentinel packet";
+  }
+
+  auto cw = std::make_unique<CloseWait>(worker_, std::vector<ngtcp2_cid>{idcid},
+                                        std::move(buf), d);
+
+  add_close_wait(cw.get());
+
+  cw.release();
+
+  return 0;
+}
+
+int QUICConnectionHandler::send_version_negotiation(
+    const UpstreamAddr *faddr, uint32_t version, const uint8_t *ini_dcid,
+    size_t ini_dcidlen, const uint8_t *ini_scid, size_t ini_scidlen,
+    const Address &remote_addr, const Address &local_addr) {
+  std::array<uint32_t, 2> sv;
+
+  sv[0] = generate_reserved_version(remote_addr, version);
+  sv[1] = NGTCP2_PROTO_VER_V1;
+
+  std::array<uint8_t, NGTCP2_MAX_UDP_PAYLOAD_SIZE> buf;
+
+  uint8_t rand_byte;
+  util::random_bytes(&rand_byte, &rand_byte + 1, worker_->get_randgen());
+
+  auto nwrite = ngtcp2_pkt_write_version_negotiation(
+      buf.data(), buf.size(), rand_byte, ini_scid, ini_scidlen, ini_dcid,
+      ini_dcidlen, sv.data(), sv.size());
+  if (nwrite < 0) {
+    LOG(ERROR) << "ngtcp2_pkt_write_version_negotiation: "
+               << ngtcp2_strerror(nwrite);
+    return -1;
+  }
+
+  return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
+                          &local_addr.su.sa, local_addr.len, buf.data(), nwrite,
+                          0);
+}
+
+int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr,
+                                                const uint8_t *dcid,
+                                                size_t dcidlen,
+                                                const Address &remote_addr,
+                                                const Address &local_addr) {
+  if (stateless_reset_bucket_ == 0) {
+    if (LOG_ENABLED(INFO)) {
+      LOG(INFO) << "Stateless Reset bucket has been depleted";
+    }
+
+    return 0;
+  }
+
+  --stateless_reset_bucket_;
+
+  if (!ev_is_active(&stateless_reset_bucket_regen_timer_)) {
+    ev_timer_again(worker_->get_loop(), &stateless_reset_bucket_regen_timer_);
+  }
+
+  int rv;
+  std::array<uint8_t, NGTCP2_STATELESS_RESET_TOKENLEN> token;
+  ngtcp2_cid cid;
+
+  ngtcp2_cid_init(&cid, dcid, dcidlen);
+
+  auto conn_handler = worker_->get_connection_handler();
+  auto &qkms = conn_handler->get_quic_keying_materials();
+  auto &qkm = qkms->keying_materials.front();
+
+  rv = generate_quic_stateless_reset_token(token.data(), cid, qkm.secret.data(),
+                                           qkm.secret.size());
+  if (rv != 0) {
+    return -1;
+  }
+
+  std::array<uint8_t, NGTCP2_MIN_STATELESS_RESET_RANDLEN> rand_bytes;
+
+  if (RAND_bytes(rand_bytes.data(), rand_bytes.size()) != 1) {
+    return -1;
+  }
+
+  std::array<uint8_t, NGTCP2_MAX_UDP_PAYLOAD_SIZE> buf;
+
+  auto nwrite =
+      ngtcp2_pkt_write_stateless_reset(buf.data(), buf.size(), token.data(),
+                                       rand_bytes.data(), rand_bytes.size());
+  if (nwrite < 0) {
+    LOG(ERROR) << "ngtcp2_pkt_write_stateless_reset: "
+               << ngtcp2_strerror(nwrite);
+    return -1;
+  }
+
+  if (LOG_ENABLED(INFO)) {
+    LOG(INFO) << "Send stateless_reset to remote="
+              << util::to_numeric_addr(&remote_addr)
+              << " dcid=" << util::format_hex(dcid, dcidlen);
+  }
+
+  return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
+                          &local_addr.su.sa, local_addr.len, buf.data(), nwrite,
+                          0);
+}
+
+int QUICConnectionHandler::send_connection_close(
+    const UpstreamAddr *faddr, uint32_t version, const ngtcp2_cid &ini_dcid,
+    const ngtcp2_cid &ini_scid, const Address &remote_addr,
+    const Address &local_addr, uint64_t error_code) {
+  std::array<uint8_t, NGTCP2_MAX_UDP_PAYLOAD_SIZE> buf;
+
+  auto nwrite = ngtcp2_crypto_write_connection_close(
+      buf.data(), buf.size(), version, &ini_scid, &ini_dcid, error_code);
+  if (nwrite < 0) {
+    LOG(ERROR) << "ngtcp2_crypto_write_connection_close failed";
+    return -1;
+  }
+
+  if (LOG_ENABLED(INFO)) {
+    LOG(INFO) << "Send Initial CONNECTION_CLOSE with error_code=" << log::hex
+              << error_code << log::dec
+              << " to remote=" << util::to_numeric_addr(&remote_addr)
+              << " dcid=" << util::format_hex(ini_scid.data, ini_scid.datalen)
+              << " scid=" << util::format_hex(ini_dcid.data, ini_dcid.datalen);
+  }
+
+  return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
+                          &local_addr.su.sa, local_addr.len, buf.data(), nwrite,
+                          0);
+}
+
+void QUICConnectionHandler::add_connection_id(const ngtcp2_cid &cid,
+                                              ClientHandler *handler) {
+  connections_.emplace(cid, handler);
+}
+
+void QUICConnectionHandler::remove_connection_id(const ngtcp2_cid &cid) {
+  connections_.erase(cid);
+}
+
+void QUICConnectionHandler::add_close_wait(CloseWait *cw) {
+  for (auto &cid : cw->scids) {
+    close_waits_.emplace(cid, cw);
+  }
+}
+
+void QUICConnectionHandler::remove_close_wait(const CloseWait *cw) {
+  for (auto &cid : cw->scids) {
+    close_waits_.erase(cid);
+  }
+}
+
+void QUICConnectionHandler::on_stateless_reset_bucket_regen() {
+  assert(stateless_reset_bucket_ < SHRPX_QUIC_STATELESS_RESET_BURST);
+
+  if (++stateless_reset_bucket_ == SHRPX_QUIC_STATELESS_RESET_BURST) {
+    ev_timer_stop(worker_->get_loop(), &stateless_reset_bucket_regen_timer_);
+  }
+}
+
+static void close_wait_timeoutcb(struct ev_loop *loop, ev_timer *w,
+                                 int revents) {
+  auto cw = static_cast<CloseWait *>(w->data);
+
+  if (LOG_ENABLED(INFO)) {
+    LOG(INFO) << "close-wait period finished";
+  }
+
+  auto quic_conn_handler = cw->worker->get_quic_connection_handler();
+  quic_conn_handler->remove_close_wait(cw);
+
+  delete cw;
+}
+
+CloseWait::CloseWait(Worker *worker, std::vector<ngtcp2_cid> scids,
+                     std::vector<uint8_t> pkt, ev_tstamp period)
+    : worker{worker},
+      scids{std::move(scids)},
+      pkt{std::move(pkt)},
+      bytes_recv{0},
+      bytes_sent{0},
+      num_pkts_recv{0},
+      next_pkts_recv{1} {
+  ++worker->get_worker_stat()->num_close_waits;
+
+  ev_timer_init(&timer, close_wait_timeoutcb, period, 0.);
+  timer.data = this;
+
+  ev_timer_start(worker->get_loop(), &timer);
+}
+
+CloseWait::~CloseWait() {
+  auto loop = worker->get_loop();
+
+  ev_timer_stop(loop, &timer);
+
+  auto worker_stat = worker->get_worker_stat();
+  --worker_stat->num_close_waits;
+
+  if (worker->get_graceful_shutdown() && worker_stat->num_connections == 0 &&
+      worker_stat->num_close_waits == 0) {
+    ev_break(loop);
+  }
+}
+
+int CloseWait::handle_packet(const UpstreamAddr *faddr,
+                             const Address &remote_addr,
+                             const Address &local_addr, const uint8_t *data,
+                             size_t datalen) {
+  if (pkt.empty()) {
+    return 0;
+  }
+
+  ++num_pkts_recv;
+  bytes_recv += datalen;
+
+  if (bytes_sent + pkt.size() > 3 * bytes_recv ||
+      next_pkts_recv > num_pkts_recv) {
+    return 0;
+  }
+
+  if (quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
+                       &local_addr.su.sa, local_addr.len, pkt.data(),
+                       pkt.size(), 0) != 0) {
+    return -1;
+  }
+
+  next_pkts_recv *= 2;
+  bytes_sent += pkt.size();
+
+  return 0;
+}
+
+} // namespace shrpx
diff --git a/src/shrpx_quic_connection_handler.h b/src/shrpx_quic_connection_handler.h
new file mode 100644 (file)
index 0000000..39c1b7d
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef SHRPX_QUIC_CONNECTION_HANDLER_H
+#define SHRPX_QUIC_CONNECTION_HANDLER_H
+
+#include "shrpx.h"
+
+#include <memory>
+#include <unordered_map>
+#include <string>
+#include <vector>
+
+#include <ngtcp2/ngtcp2.h>
+
+#include <ev.h>
+
+#include "shrpx_quic.h"
+#include "network.h"
+
+using namespace nghttp2;
+
+namespace shrpx {
+
+struct UpstreamAddr;
+class ClientHandler;
+class Worker;
+
+// CloseWait handles packets received in close-wait (draining or
+// closing period).
+struct CloseWait {
+  CloseWait(Worker *worker, std::vector<ngtcp2_cid> scids,
+            std::vector<uint8_t> pkt, ev_tstamp period);
+  ~CloseWait();
+
+  int handle_packet(const UpstreamAddr *faddr, const Address &remote_addr,
+                    const Address &local_addr, const uint8_t *data,
+                    size_t datalen);
+
+  Worker *worker;
+  // Source Connection IDs of the connection.
+  std::vector<ngtcp2_cid> scids;
+  // QUIC packet which is sent in response to the incoming packet.  It
+  // might be empty.
+  std::vector<uint8_t> pkt;
+  // Close-wait (draining or closing period) timer.
+  ev_timer timer;
+  // The number of bytes received during close-wait period.
+  size_t bytes_recv;
+  // The number of bytes sent during close-wait period.
+  size_t bytes_sent;
+  // The number of packets received during close-wait period.
+  size_t num_pkts_recv;
+  // If the number of packets received reaches this number, send a
+  // QUIC packet.
+  size_t next_pkts_recv;
+};
+
+class QUICConnectionHandler {
+public:
+  QUICConnectionHandler(Worker *worker);
+  ~QUICConnectionHandler();
+  int handle_packet(const UpstreamAddr *faddr, const Address &remote_addr,
+                    const Address &local_addr, const uint8_t *data,
+                    size_t datalen);
+  // Send Retry packet.  |ini_dcid| is the destination Connection ID
+  // which appeared in Client Initial packet and its length is
+  // |dcidlen|.  |ini_scid| is the source Connection ID which appeared
+  // in Client Initial packet and its length is |scidlen|.
+  int send_retry(const UpstreamAddr *faddr, uint32_t version,
+                 const uint8_t *ini_dcid, size_t ini_dcidlen,
+                 const uint8_t *ini_scid, size_t ini_scidlen,
+                 const Address &remote_addr, const Address &local_addr);
+  // Send Version Negotiation packet.  |ini_dcid| is the destination
+  // Connection ID which appeared in Client Initial packet and its
+  // length is |dcidlen|.  |ini_scid| is the source Connection ID
+  // which appeared in Client Initial packet and its length is
+  // |scidlen|.
+  int send_version_negotiation(const UpstreamAddr *faddr, uint32_t version,
+                               const uint8_t *ini_dcid, size_t ini_dcidlen,
+                               const uint8_t *ini_scid, size_t ini_scidlen,
+                               const Address &remote_addr,
+                               const Address &local_addr);
+  int send_stateless_reset(const UpstreamAddr *faddr, const uint8_t *dcid,
+                           size_t dcidlen, const Address &remote_addr,
+                           const Address &local_addr);
+  // Send Initial CONNECTION_CLOSE.  |ini_dcid| is the destination
+  // Connection ID which appeared in Client Initial packet.
+  // |ini_scid| is the source Connection ID which appeared in Client
+  // Initial packet.
+  int send_connection_close(const UpstreamAddr *faddr, uint32_t version,
+                            const ngtcp2_cid &ini_dcid,
+                            const ngtcp2_cid &ini_scid,
+                            const Address &remote_addr,
+                            const Address &local_addr, uint64_t error_code);
+  ClientHandler *handle_new_connection(const UpstreamAddr *faddr,
+                                       const Address &remote_addr,
+                                       const Address &local_addr,
+                                       const ngtcp2_pkt_hd &hd,
+                                       const ngtcp2_cid *odcid,
+                                       const uint8_t *token, size_t tokenlen);
+  void add_connection_id(const ngtcp2_cid &cid, ClientHandler *handler);
+  void remove_connection_id(const ngtcp2_cid &cid);
+
+  void add_close_wait(CloseWait *cw);
+  void remove_close_wait(const CloseWait *cw);
+
+  void on_stateless_reset_bucket_regen();
+
+private:
+  Worker *worker_;
+  std::unordered_map<ngtcp2_cid, ClientHandler *> connections_;
+  std::unordered_map<ngtcp2_cid, CloseWait *> close_waits_;
+  ev_timer stateless_reset_bucket_regen_timer_;
+  size_t stateless_reset_bucket_;
+};
+
+} // namespace shrpx
+
+#endif // SHRPX_QUIC_CONNECTION_HANDLER_H
diff --git a/src/shrpx_quic_listener.cc b/src/shrpx_quic_listener.cc
new file mode 100644 (file)
index 0000000..b06ec55
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "shrpx_quic_listener.h"
+#include "shrpx_worker.h"
+#include "shrpx_config.h"
+#include "shrpx_log.h"
+
+namespace shrpx {
+
+namespace {
+void readcb(struct ev_loop *loop, ev_io *w, int revent) {
+  auto l = static_cast<QUICListener *>(w->data);
+  l->on_read();
+}
+} // namespace
+
+QUICListener::QUICListener(const UpstreamAddr *faddr, Worker *worker)
+    : faddr_{faddr}, worker_{worker} {
+  ev_io_init(&rev_, readcb, faddr_->fd, EV_READ);
+  rev_.data = this;
+  ev_io_start(worker_->get_loop(), &rev_);
+}
+
+QUICListener::~QUICListener() {
+  ev_io_stop(worker_->get_loop(), &rev_);
+  close(faddr_->fd);
+}
+
+void QUICListener::on_read() {
+  sockaddr_union su;
+  std::array<uint8_t, 64_k> buf;
+  size_t pktcnt = 0;
+  iovec msg_iov{buf.data(), buf.size()};
+
+  msghdr msg{};
+  msg.msg_name = &su;
+  msg.msg_iov = &msg_iov;
+  msg.msg_iovlen = 1;
+
+  uint8_t msg_ctrl[CMSG_SPACE(sizeof(in6_pktinfo))];
+  msg.msg_control = msg_ctrl;
+
+  auto quic_conn_handler = worker_->get_quic_connection_handler();
+
+  for (; pktcnt < 10;) {
+    msg.msg_namelen = sizeof(su);
+    msg.msg_controllen = sizeof(msg_ctrl);
+
+    auto nread = recvmsg(faddr_->fd, &msg, 0);
+    if (nread == -1) {
+      return;
+    }
+
+    ++pktcnt;
+
+    Address local_addr{};
+    if (util::msghdr_get_local_addr(local_addr, &msg, su.storage.ss_family) !=
+        0) {
+      continue;
+    }
+
+    util::set_port(local_addr, faddr_->port);
+
+    if (LOG_ENABLED(INFO)) {
+      LOG(INFO) << "QUIC received packet: local="
+                << util::to_numeric_addr(&local_addr)
+                << " remote=" << util::to_numeric_addr(&su.sa, msg.msg_namelen)
+                << " " << nread << " bytes";
+    }
+
+    if (nread == 0) {
+      continue;
+    }
+
+    Address remote_addr;
+    remote_addr.su = su;
+    remote_addr.len = msg.msg_namelen;
+
+    quic_conn_handler->handle_packet(faddr_, remote_addr, local_addr,
+                                     buf.data(), nread);
+  }
+}
+
+} // namespace shrpx
diff --git a/src/shrpx_quic_listener.h b/src/shrpx_quic_listener.h
new file mode 100644 (file)
index 0000000..3d70921
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2021 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef SHRPX_QUIC_LISTENER_H
+#define SHRPX_QUIC_LISTENER_H
+
+#include "shrpx.h"
+
+#include <ev.h>
+
+namespace shrpx {
+
+struct UpstreamAddr;
+class Worker;
+
+class QUICListener {
+public:
+  QUICListener(const UpstreamAddr *faddr, Worker *worker);
+  ~QUICListener();
+  void on_read();
+
+private:
+  const UpstreamAddr *faddr_;
+  Worker *worker_;
+  ev_io rev_;
+};
+
+} // namespace shrpx
+
+#endif // SHRPX_QUIC_LISTENER_H
index f05ae64..0d4f921 100644 (file)
@@ -108,9 +108,10 @@ void RateLimit::stopw() {
 }
 
 void RateLimit::handle_tls_pending_read() {
-  if (!conn_ || !conn_->tls.ssl || !conn_->tls.initial_handshake_done ||
+  if (!conn_ || !conn_->tls.ssl ||
       (SSL_pending(conn_->tls.ssl) == 0 && conn_->tls.rbuf.rleft() == 0 &&
-       conn_->tls.earlybuf.rleft() == 0)) {
+       (!conn_->tls.initial_handshake_done ||
+        conn_->tls.earlybuf.rleft() == 0))) {
     return;
   }
 
index 5070d16..63fcc07 100644 (file)
@@ -110,7 +110,7 @@ int signal_set_handler(void (*handler)(int), Signals &&sigs) {
 } // namespace
 
 namespace {
-constexpr auto master_proc_ign_signals = std::array<int, 1>{SIGPIPE};
+constexpr auto main_proc_ign_signals = std::array<int, 1>{SIGPIPE};
 } // namespace
 
 namespace {
@@ -119,12 +119,12 @@ constexpr auto worker_proc_ign_signals =
                        GRACEFUL_SHUTDOWN_SIGNAL, RELOAD_SIGNAL, SIGPIPE};
 } // namespace
 
-int shrpx_signal_set_master_proc_ign_handler() {
-  return signal_set_handler(SIG_IGN, master_proc_ign_signals);
+int shrpx_signal_set_main_proc_ign_handler() {
+  return signal_set_handler(SIG_IGN, main_proc_ign_signals);
 }
 
-int shrpx_signal_unset_master_proc_ign_handler() {
-  return signal_set_handler(SIG_DFL, master_proc_ign_signals);
+int shrpx_signal_unset_main_proc_ign_handler() {
+  return signal_set_handler(SIG_DFL, main_proc_ign_signals);
 }
 
 int shrpx_signal_set_worker_proc_ign_handler() {
index 8f668ae..152ca36 100644 (file)
@@ -49,8 +49,8 @@ int shrpx_signal_unblock_all();
 // -1.  The errno will indicate the error.
 int shrpx_signal_set(sigset_t *set);
 
-int shrpx_signal_set_master_proc_ign_handler();
-int shrpx_signal_unset_master_proc_ign_handler();
+int shrpx_signal_set_main_proc_ign_handler();
+int shrpx_signal_unset_main_proc_ign_handler();
 
 int shrpx_signal_set_worker_proc_ign_handler();
 int shrpx_signal_unset_worker_proc_ign_handler();
index c562530..7913d86 100644 (file)
@@ -40,6 +40,8 @@
 
 #include <iostream>
 
+#include "ssl_compat.h"
+
 #include <openssl/crypto.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #ifndef OPENSSL_NO_OCSP
 #  include <openssl/ocsp.h>
 #endif // OPENSSL_NO_OCSP
+#if OPENSSL_3_0_0_API
+#  include <openssl/params.h>
+#  include <openssl/core_names.h>
+#  include <openssl/decoder.h>
+#endif // OPENSSL_3_0_0_API
 
 #include <nghttp2/nghttp2.h>
 
+#ifdef ENABLE_HTTP3
+#  include <ngtcp2/ngtcp2.h>
+#  include <ngtcp2/ngtcp2_crypto.h>
+#  ifdef HAVE_LIBNGTCP2_CRYPTO_OPENSSL
+#    include <ngtcp2/ngtcp2_crypto_openssl.h>
+#  endif // HAVE_LIBNGTCP2_CRYPTO_OPENSSL
+#  ifdef HAVE_LIBNGTCP2_CRYPTO_BORINGSSL
+#    include <ngtcp2/ngtcp2_crypto_boringssl.h>
+#  endif // HAVE_LIBNGTCP2_CRYPTO_BORINGSSL
+#endif   // ENABLE_HTTP3
+
 #include "shrpx_log.h"
 #include "shrpx_client_handler.h"
 #include "shrpx_config.h"
 #include "shrpx_memcached_request.h"
 #include "shrpx_memcached_dispatcher.h"
 #include "shrpx_connection_handler.h"
+#ifdef ENABLE_HTTP3
+#  include "shrpx_http3_upstream.h"
+#endif // ENABLE_HTTP3
 #include "util.h"
 #include "tls.h"
 #include "template.h"
-#include "ssl_compat.h"
 #include "timegm.h"
 
 using namespace nghttp2;
@@ -180,7 +200,13 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
 
   auto hostname = StringRef{std::begin(buf), end_buf};
 
+#ifdef ENABLE_HTTP3
+  auto cert_tree = conn->proto == Proto::HTTP3
+                       ? worker->get_quic_cert_lookup_tree()
+                       : worker->get_cert_lookup_tree();
+#else  // !ENABLE_HTTP3
   auto cert_tree = worker->get_cert_lookup_tree();
+#endif // !ENABLE_HTTP3
 
   auto idx = cert_tree->lookup(hostname);
   if (idx == -1) {
@@ -191,15 +217,56 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
 
   auto conn_handler = worker->get_connection_handler();
 
+#ifdef ENABLE_HTTP3
+  const auto &ssl_ctx_list = conn->proto == Proto::HTTP3
+                                 ? conn_handler->get_quic_indexed_ssl_ctx(idx)
+                                 : conn_handler->get_indexed_ssl_ctx(idx);
+#else  // !ENABLE_HTTP3
   const auto &ssl_ctx_list = conn_handler->get_indexed_ssl_ctx(idx);
+#endif // !ENABLE_HTTP3
+
   assert(!ssl_ctx_list.empty());
 
 #if !defined(OPENSSL_IS_BORINGSSL) && !LIBRESSL_IN_USE &&                      \
     OPENSSL_VERSION_NUMBER >= 0x10002000L
+  auto num_sigalgs =
+      SSL_get_sigalgs(ssl, 0, nullptr, nullptr, nullptr, nullptr, nullptr);
+
+  for (idx = 0; idx < num_sigalgs; ++idx) {
+    int signhash;
+
+    SSL_get_sigalgs(ssl, idx, nullptr, nullptr, &signhash, nullptr, nullptr);
+    switch (signhash) {
+    case NID_ecdsa_with_SHA256:
+    case NID_ecdsa_with_SHA384:
+    case NID_ecdsa_with_SHA512:
+      break;
+    default:
+      continue;
+    }
+
+    break;
+  }
+
+  if (idx == num_sigalgs) {
+    SSL_set_SSL_CTX(ssl, ssl_ctx_list[0]);
+
+    return SSL_TLSEXT_ERR_OK;
+  }
+
   auto num_shared_curves = SSL_get_shared_curve(ssl, -1);
 
   for (auto i = 0; i < num_shared_curves; ++i) {
     auto shared_curve = SSL_get_shared_curve(ssl, i);
+#  if OPENSSL_3_0_0_API
+    // It looks like only short name is defined in OpenSSL.  No idea
+    // which one to use because it is unknown that which one
+    // EVP_PKEY_get_utf8_string_param("group") returns.
+    auto shared_curve_name = OBJ_nid2sn(shared_curve);
+    if (shared_curve_name == nullptr) {
+      continue;
+    }
+#  endif // OPENSSL_3_0_0_API
 
     for (auto ssl_ctx : ssl_ctx_list) {
       auto cert = SSL_CTX_get0_certificate(ssl_ctx);
@@ -214,11 +281,23 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
         continue;
       }
 
-#  if OPENSSL_1_1_API
+#  if OPENSSL_3_0_0_API
+      std::array<char, 64> curve_name;
+      if (!EVP_PKEY_get_utf8_string_param(pubkey, "group", curve_name.data(),
+                                          curve_name.size(), nullptr)) {
+        continue;
+      }
+
+      if (strcmp(shared_curve_name, curve_name.data()) == 0) {
+        SSL_set_SSL_CTX(ssl, ssl_ctx);
+        return SSL_TLSEXT_ERR_OK;
+      }
+#  else // !OPENSSL_3_0_0_API
+#    if OPENSSL_1_1_API
       auto eckey = EVP_PKEY_get0_EC_KEY(pubkey);
-#  else  // !OPENSSL_1_1_API
+#    else  // !OPENSSL_1_1_API
       auto eckey = EVP_PKEY_get1_EC_KEY(pubkey);
-#  endif // !OPENSSL_1_1_API
+#    endif // !OPENSSL_1_1_API
 
       if (eckey == nullptr) {
         continue;
@@ -227,15 +306,16 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
       auto ecgroup = EC_KEY_get0_group(eckey);
       auto cert_curve = EC_GROUP_get_curve_name(ecgroup);
 
-#  if !OPENSSL_1_1_API
+#    if !OPENSSL_1_1_API
       EC_KEY_free(eckey);
       EVP_PKEY_free(pubkey);
-#  endif // !OPENSSL_1_1_API
+#    endif // !OPENSSL_1_1_API
 
       if (shared_curve == cert_curve) {
         SSL_set_SSL_CTX(ssl, ssl_ctx);
         return SSL_TLSEXT_ERR_OK;
       }
+#  endif   // !OPENSSL_3_0_0_API
     }
   }
 #endif // !defined(OPENSSL_IS_BORINGSSL) && !LIBRESSL_IN_USE &&
@@ -449,7 +529,13 @@ SSL_SESSION *tls_session_get_cb(SSL *ssl,
 
 namespace {
 int ticket_key_cb(SSL *ssl, unsigned char *key_name, unsigned char *iv,
-                  EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc) {
+                  EVP_CIPHER_CTX *ctx,
+#if OPENSSL_3_0_0_API
+                  EVP_MAC_CTX *hctx,
+#else  // !OPENSSL_3_0_0_API
+                  HMAC_CTX *hctx,
+#endif // !OPENSSL_3_0_0_API
+                  int enc) {
   auto conn = static_cast<Connection *>(SSL_get_app_data(ssl));
   auto handler = static_cast<ClientHandler *>(conn->data);
   auto worker = handler->get_worker();
@@ -482,8 +568,25 @@ int ticket_key_cb(SSL *ssl, unsigned char *key_name, unsigned char *iv,
 
     EVP_EncryptInit_ex(ctx, get_config()->tls.ticket.cipher, nullptr,
                        key.data.enc_key.data(), iv);
+#if OPENSSL_3_0_0_API
+    std::array<OSSL_PARAM, 3> params{
+        OSSL_PARAM_construct_octet_string(
+            OSSL_MAC_PARAM_KEY, key.data.hmac_key.data(), key.hmac_keylen),
+        OSSL_PARAM_construct_utf8_string(
+            OSSL_MAC_PARAM_DIGEST,
+            const_cast<char *>(EVP_MD_get0_name(key.hmac)), 0),
+        OSSL_PARAM_construct_end(),
+    };
+    if (!EVP_MAC_CTX_set_params(hctx, params.data())) {
+      if (LOG_ENABLED(INFO)) {
+        CLOG(INFO, handler) << "EVP_MAC_CTX_set_params failed";
+      }
+      return -1;
+    }
+#else  // !OPENSSL_3_0_0_API
     HMAC_Init_ex(hctx, key.data.hmac_key.data(), key.hmac_keylen, key.hmac,
                  nullptr);
+#endif // !OPENSSL_3_0_0_API
     return 1;
   }
 
@@ -510,10 +613,35 @@ int ticket_key_cb(SSL *ssl, unsigned char *key_name, unsigned char *iv,
   }
 
   auto &key = keys[i];
+#if OPENSSL_3_0_0_API
+  std::array<OSSL_PARAM, 3> params{
+      OSSL_PARAM_construct_octet_string(
+          OSSL_MAC_PARAM_KEY, key.data.hmac_key.data(), key.hmac_keylen),
+      OSSL_PARAM_construct_utf8_string(
+          OSSL_MAC_PARAM_DIGEST, const_cast<char *>(EVP_MD_get0_name(key.hmac)),
+          0),
+      OSSL_PARAM_construct_end(),
+  };
+  if (!EVP_MAC_CTX_set_params(hctx, params.data())) {
+    if (LOG_ENABLED(INFO)) {
+      CLOG(INFO, handler) << "EVP_MAC_CTX_set_params failed";
+    }
+    return -1;
+  }
+#else  // !OPENSSL_3_0_0_API
   HMAC_Init_ex(hctx, key.data.hmac_key.data(), key.hmac_keylen, key.hmac,
                nullptr);
+#endif // !OPENSSL_3_0_0_API
   EVP_DecryptInit_ex(ctx, key.cipher, nullptr, key.data.enc_key.data(), iv);
 
+#ifdef TLS1_3_VERSION
+  // If ticket_key_cb is not set, OpenSSL always renew ticket for
+  // TLSv1.3.
+  if (SSL_version(ssl) == TLS1_3_VERSION) {
+    return 2;
+  }
+#endif // TLS1_3_VERSION
+
   return i == 0 ? 1 : 2;
 }
 } // namespace
@@ -575,7 +703,42 @@ int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
 } // namespace
 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
 
-#if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L
+#ifdef ENABLE_HTTP3
+#  if OPENSSL_VERSION_NUMBER >= 0x10002000L
+namespace {
+int quic_alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
+                              unsigned char *outlen, const unsigned char *in,
+                              unsigned int inlen, void *arg) {
+  constexpr StringRef alpnlist[] = {
+      StringRef::from_lit("h3"),
+      StringRef::from_lit("h3-29"),
+  };
+
+  for (auto &alpn : alpnlist) {
+    for (auto p = in, end = in + inlen; p < end;) {
+      auto proto_id = p + 1;
+      auto proto_len = *p;
+
+      if (alpn.size() == proto_len &&
+          memcmp(alpn.byte(), proto_id, alpn.size()) == 0) {
+        *out = proto_id;
+        *outlen = proto_len;
+
+        return SSL_TLSEXT_ERR_OK;
+      }
+
+      p += 1 + proto_len;
+    }
+  }
+
+  return SSL_TLSEXT_ERR_ALERT_FATAL;
+}
+} // namespace
+#  endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
+#endif   // ENABLE_HTTP3
+
+#if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L &&               \
+    !defined(OPENSSL_IS_BORINGSSL)
 
 #  ifndef TLSEXT_TYPE_signed_certificate_timestamp
 #    define TLSEXT_TYPE_signed_certificate_timestamp 18
@@ -665,7 +828,8 @@ int legacy_sct_parse_cb(SSL *ssl, unsigned int ext_type,
 } // namespace
 
 #  endif // !OPENSSL_1_1_1_API
-#endif   // !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L
+#endif   // !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L &&
+         // !defined(OPENSSL_IS_BORINGSSL)
 
 #ifndef OPENSSL_NO_PSK
 namespace {
@@ -763,7 +927,7 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
                             neverbleed_t *nb
 #endif // HAVE_NEVERBLEED
 ) {
-  auto ssl_ctx = SSL_CTX_new(SSLv23_server_method());
+  auto ssl_ctx = SSL_CTX_new(TLS_server_method());
   if (!ssl_ctx) {
     LOG(FATAL) << ERR_error_string(ERR_get_error(), nullptr);
     DIE();
@@ -775,14 +939,14 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
       SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_SINGLE_ECDH_USE |
       SSL_OP_SINGLE_DH_USE |
       SSL_OP_CIPHER_SERVER_PREFERENCE
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
       // The reason for disabling built-in anti-replay in OpenSSL is
       // that it only works if client gets back to the same server.
       // The freshness check described in
       // https://tools.ietf.org/html/rfc8446#section-8.3 is still
       // performed.
       | SSL_OP_NO_ANTI_REPLAY
-#endif // OPENSSL_1_1_1_API
+#endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
       ;
 
   auto config = mod_config();
@@ -813,13 +977,13 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
     DIE();
   }
 
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
   if (SSL_CTX_set_ciphersuites(ssl_ctx, tlsconf.tls13_ciphers.c_str()) == 0) {
     LOG(FATAL) << "SSL_CTX_set_ciphersuites " << tlsconf.tls13_ciphers
                << " failed: " << ERR_error_string(ERR_get_error(), nullptr);
     DIE();
   }
-#endif // OPENSSL_1_1_1_API
+#endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
 
 #ifndef OPENSSL_NO_EC
 #  if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L
@@ -849,12 +1013,30 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
 
   if (!tlsconf.dh_param_file.empty()) {
     // Read DH parameters from file
-    auto bio = BIO_new_file(tlsconf.dh_param_file.c_str(), "r");
+    auto bio = BIO_new_file(tlsconf.dh_param_file.c_str(), "rb");
     if (bio == nullptr) {
       LOG(FATAL) << "BIO_new_file() failed: "
                  << ERR_error_string(ERR_get_error(), nullptr);
       DIE();
     }
+#if OPENSSL_3_0_0_API
+    EVP_PKEY *dh = nullptr;
+    auto dctx = OSSL_DECODER_CTX_new_for_pkey(
+        &dh, "PEM", nullptr, "DH", OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+        nullptr, nullptr);
+
+    if (!OSSL_DECODER_from_bio(dctx, bio)) {
+      LOG(FATAL) << "OSSL_DECODER_from_bio() failed: "
+                 << ERR_error_string(ERR_get_error(), nullptr);
+      DIE();
+    }
+
+    if (SSL_CTX_set0_tmp_dh_pkey(ssl_ctx, dh) != 1) {
+      LOG(FATAL) << "SSL_CTX_set0_tmp_dh_pkey failed: "
+                 << ERR_error_string(ERR_get_error(), nullptr);
+      DIE();
+    }
+#else  // !OPENSSL_3_0_0_API
     auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
     if (dh == nullptr) {
       LOG(FATAL) << "PEM_read_bio_DHparams() failed: "
@@ -863,6 +1045,7 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
     }
     SSL_CTX_set_tmp_dh(ssl_ctx, dh);
     DH_free(dh);
+#endif // !OPENSSL_3_0_0_API
     BIO_free(bio);
   }
 
@@ -942,7 +1125,11 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
                        verify_callback);
   }
   SSL_CTX_set_tlsext_servername_callback(ssl_ctx, servername_callback);
+#if OPENSSL_3_0_0_API
+  SSL_CTX_set_tlsext_ticket_key_evp_cb(ssl_ctx, ticket_key_cb);
+#else  // !OPENSSL_3_0_0_API
   SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx, ticket_key_cb);
+#endif // !OPENSSL_3_0_0_API
 #ifndef OPENSSL_IS_BORINGSSL
   SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb);
 #endif // OPENSSL_IS_BORINGSSL
@@ -961,6 +1148,12 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
   SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, nullptr);
 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
 
+  auto tls_ctx_data = new TLSContextData();
+  tls_ctx_data->cert_file = cert_file;
+  tls_ctx_data->sct_data = sct_data;
+
+  SSL_CTX_set_app_data(ssl_ctx, tls_ctx_data);
+
 #if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L &&               \
     !defined(OPENSSL_IS_BORINGSSL)
   // SSL_extension_supported(TLSEXT_TYPE_signed_certificate_timestamp)
@@ -993,29 +1186,457 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
     }
 #  endif // !OPENSSL_1_1_1_API
   }
-#endif // !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L &&
-       // !defined(OPENSSL_IS_BORINGSSL)
+#elif defined(OPENSSL_IS_BORINGSSL)
+  if (!tls_ctx_data->sct_data.empty() &&
+      SSL_CTX_set_signed_cert_timestamp_list(
+          ssl_ctx, tls_ctx_data->sct_data.data(),
+          tls_ctx_data->sct_data.size()) != 1) {
+    LOG(FATAL) << "SSL_CTX_set_signed_cert_timestamp_list failed: "
+               << ERR_error_string(ERR_get_error(), nullptr);
+    DIE();
+  }
+#endif // defined(OPENSSL_IS_BORINGSSL)
 
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
   if (SSL_CTX_set_max_early_data(ssl_ctx, tlsconf.max_early_data) != 1) {
     LOG(FATAL) << "SSL_CTX_set_max_early_data failed: "
                << ERR_error_string(ERR_get_error(), nullptr);
     DIE();
   }
-#endif // OPENSSL_1_1_1_API
+#endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
 
 #ifndef OPENSSL_NO_PSK
   SSL_CTX_set_psk_server_callback(ssl_ctx, psk_server_cb);
 #endif // !LIBRESSL_NO_PSK
 
+  return ssl_ctx;
+}
+
+#ifdef ENABLE_HTTP3
+#  ifdef HAVE_LIBNGTCP2_CRYPTO_OPENSSL
+namespace {
+int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
+                                const uint8_t *rx_secret,
+                                const uint8_t *tx_secret, size_t secretlen) {
+  auto conn = static_cast<Connection *>(SSL_get_app_data(ssl));
+  auto handler = static_cast<ClientHandler *>(conn->data);
+  auto upstream = static_cast<Http3Upstream *>(handler->get_upstream());
+  auto level = ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
+
+  if (upstream->on_rx_secret(level, rx_secret, secretlen) != 0) {
+    return 0;
+  }
+
+  if (tx_secret && upstream->on_tx_secret(level, tx_secret, secretlen) != 0) {
+    return 0;
+  }
+
+  return 1;
+}
+} // namespace
+
+namespace {
+int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
+                            const uint8_t *data, size_t len) {
+  auto conn = static_cast<Connection *>(SSL_get_app_data(ssl));
+  auto handler = static_cast<ClientHandler *>(conn->data);
+  auto upstream = static_cast<Http3Upstream *>(handler->get_upstream());
+  auto level = ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
+
+  upstream->add_crypto_data(level, data, len);
+
+  return 1;
+}
+} // namespace
+
+namespace {
+int quic_flush_flight(SSL *ssl) { return 1; }
+} // namespace
+
+namespace {
+int quic_send_alert(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level, uint8_t alert) {
+  auto conn = static_cast<Connection *>(SSL_get_app_data(ssl));
+  auto handler = static_cast<ClientHandler *>(conn->data);
+  auto upstream = static_cast<Http3Upstream *>(handler->get_upstream());
+
+  if (!upstream) {
+    return 1;
+  }
+
+  upstream->set_tls_alert(alert);
+
+  return 1;
+}
+} // namespace
+
+namespace {
+auto quic_method = SSL_QUIC_METHOD{
+    quic_set_encryption_secrets,
+    quic_add_handshake_data,
+    quic_flush_flight,
+    quic_send_alert,
+};
+} // namespace
+#  endif // HAVE_LIBNGTCP2_CRYPTO_OPENSSL
+
+#  ifdef HAVE_LIBNGTCP2_CRYPTO_BORINGSSL
+namespace {
+int quic_set_read_secret(SSL *ssl, ssl_encryption_level_t ssl_level,
+                         const SSL_CIPHER *cipher, const uint8_t *secret,
+                         size_t secretlen) {
+  auto conn = static_cast<Connection *>(SSL_get_app_data(ssl));
+  auto handler = static_cast<ClientHandler *>(conn->data);
+  auto upstream = static_cast<Http3Upstream *>(handler->get_upstream());
+  auto level = ngtcp2_crypto_boringssl_from_ssl_encryption_level(ssl_level);
+
+  if (upstream->on_rx_secret(level, secret, secretlen) != 0) {
+    return 0;
+  }
+
+  return 1;
+}
+} // namespace
+
+namespace {
+int quic_set_write_secret(SSL *ssl, ssl_encryption_level_t ssl_level,
+                          const SSL_CIPHER *cipher, const uint8_t *secret,
+                          size_t secretlen) {
+  auto conn = static_cast<Connection *>(SSL_get_app_data(ssl));
+  auto handler = static_cast<ClientHandler *>(conn->data);
+  auto upstream = static_cast<Http3Upstream *>(handler->get_upstream());
+  auto level = ngtcp2_crypto_boringssl_from_ssl_encryption_level(ssl_level);
+
+  if (upstream->on_tx_secret(level, secret, secretlen) != 0) {
+    return 0;
+  }
+
+  return 1;
+}
+} // namespace
+
+namespace {
+int quic_add_handshake_data(SSL *ssl, ssl_encryption_level_t ssl_level,
+                            const uint8_t *data, size_t len) {
+  auto conn = static_cast<Connection *>(SSL_get_app_data(ssl));
+  auto handler = static_cast<ClientHandler *>(conn->data);
+  auto upstream = static_cast<Http3Upstream *>(handler->get_upstream());
+  auto level = ngtcp2_crypto_boringssl_from_ssl_encryption_level(ssl_level);
+
+  upstream->add_crypto_data(level, data, len);
+
+  return 1;
+}
+} // namespace
+
+namespace {
+int quic_flush_flight(SSL *ssl) { return 1; }
+} // namespace
+
+namespace {
+int quic_send_alert(SSL *ssl, ssl_encryption_level_t level, uint8_t alert) {
+  auto conn = static_cast<Connection *>(SSL_get_app_data(ssl));
+  auto handler = static_cast<ClientHandler *>(conn->data);
+  auto upstream = static_cast<Http3Upstream *>(handler->get_upstream());
+
+  if (!upstream) {
+    return 1;
+  }
+
+  upstream->set_tls_alert(alert);
+
+  return 1;
+}
+} // namespace
+
+namespace {
+auto quic_method = SSL_QUIC_METHOD{
+    quic_set_read_secret, quic_set_write_secret, quic_add_handshake_data,
+    quic_flush_flight,    quic_send_alert,
+};
+} // namespace
+#  endif // HAVE_LIBNGTCP2_CRYPTO_BORINGSSL
+
+SSL_CTX *create_quic_ssl_context(const char *private_key_file,
+                                 const char *cert_file,
+                                 const std::vector<uint8_t> &sct_data
+#  ifdef HAVE_NEVERBLEED
+                                 ,
+                                 neverbleed_t *nb
+#  endif // HAVE_NEVERBLEED
+) {
+  auto ssl_ctx = SSL_CTX_new(TLS_server_method());
+  if (!ssl_ctx) {
+    LOG(FATAL) << ERR_error_string(ERR_get_error(), nullptr);
+    DIE();
+  }
+
+  constexpr auto ssl_opts =
+      (SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) |
+      SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_SINGLE_ECDH_USE |
+      SSL_OP_SINGLE_DH_USE |
+      SSL_OP_CIPHER_SERVER_PREFERENCE
+#  if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+      // The reason for disabling built-in anti-replay in OpenSSL is
+      // that it only works if client gets back to the same server.
+      // The freshness check described in
+      // https://tools.ietf.org/html/rfc8446#section-8.3 is still
+      // performed.
+      | SSL_OP_NO_ANTI_REPLAY
+#  endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+      ;
+
+  auto config = mod_config();
+  auto &tlsconf = config->tls;
+
+  SSL_CTX_set_options(ssl_ctx, ssl_opts);
+
+  SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
+  SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
+
+  const unsigned char sid_ctx[] = "shrpx";
+  SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx) - 1);
+  SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_OFF);
+
+  SSL_CTX_set_timeout(ssl_ctx, tlsconf.session_timeout.count());
+
+  if (SSL_CTX_set_cipher_list(ssl_ctx, tlsconf.ciphers.c_str()) == 0) {
+    LOG(FATAL) << "SSL_CTX_set_cipher_list " << tlsconf.ciphers
+               << " failed: " << ERR_error_string(ERR_get_error(), nullptr);
+    DIE();
+  }
+
+#  if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+  if (SSL_CTX_set_ciphersuites(ssl_ctx, tlsconf.tls13_ciphers.c_str()) == 0) {
+    LOG(FATAL) << "SSL_CTX_set_ciphersuites " << tlsconf.tls13_ciphers
+               << " failed: " << ERR_error_string(ERR_get_error(), nullptr);
+    DIE();
+  }
+#  endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+
+#  ifndef OPENSSL_NO_EC
+#    if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L
+  if (SSL_CTX_set1_curves_list(ssl_ctx, tlsconf.ecdh_curves.c_str()) != 1) {
+    LOG(FATAL) << "SSL_CTX_set1_curves_list " << tlsconf.ecdh_curves
+               << " failed";
+    DIE();
+  }
+#      if !defined(OPENSSL_IS_BORINGSSL) && !OPENSSL_1_1_API
+  // It looks like we need this function call for OpenSSL 1.0.2.  This
+  // function was deprecated in OpenSSL 1.1.0 and BoringSSL.
+  SSL_CTX_set_ecdh_auto(ssl_ctx, 1);
+#      endif // !defined(OPENSSL_IS_BORINGSSL) && !OPENSSL_1_1_API
+#    else    // LIBRESSL_LEGACY_API || OPENSSL_VERSION_NUBMER < 0x10002000L
+  // Use P-256, which is sufficiently secure at the time of this
+  // writing.
+  auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+  if (ecdh == nullptr) {
+    LOG(FATAL) << "EC_KEY_new_by_curv_name failed: "
+               << ERR_error_string(ERR_get_error(), nullptr);
+    DIE();
+  }
+  SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
+  EC_KEY_free(ecdh);
+#    endif   // LIBRESSL_LEGACY_API || OPENSSL_VERSION_NUBMER < 0x10002000L
+#  endif     // OPENSSL_NO_EC
+
+  if (!tlsconf.dh_param_file.empty()) {
+    // Read DH parameters from file
+    auto bio = BIO_new_file(tlsconf.dh_param_file.c_str(), "rb");
+    if (bio == nullptr) {
+      LOG(FATAL) << "BIO_new_file() failed: "
+                 << ERR_error_string(ERR_get_error(), nullptr);
+      DIE();
+    }
+#  if OPENSSL_3_0_0_API
+    EVP_PKEY *dh = nullptr;
+    auto dctx = OSSL_DECODER_CTX_new_for_pkey(
+        &dh, "PEM", nullptr, "DH", OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+        nullptr, nullptr);
+
+    if (!OSSL_DECODER_from_bio(dctx, bio)) {
+      LOG(FATAL) << "OSSL_DECODER_from_bio() failed: "
+                 << ERR_error_string(ERR_get_error(), nullptr);
+      DIE();
+    }
+
+    if (SSL_CTX_set0_tmp_dh_pkey(ssl_ctx, dh) != 1) {
+      LOG(FATAL) << "SSL_CTX_set0_tmp_dh_pkey failed: "
+                 << ERR_error_string(ERR_get_error(), nullptr);
+      DIE();
+    }
+#  else  // !OPENSSL_3_0_0_API
+    auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
+    if (dh == nullptr) {
+      LOG(FATAL) << "PEM_read_bio_DHparams() failed: "
+                 << ERR_error_string(ERR_get_error(), nullptr);
+      DIE();
+    }
+    SSL_CTX_set_tmp_dh(ssl_ctx, dh);
+    DH_free(dh);
+#  endif // !OPENSSL_3_0_0_API
+    BIO_free(bio);
+  }
+
+  SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
+
+  if (SSL_CTX_set_default_verify_paths(ssl_ctx) != 1) {
+    LOG(WARN) << "Could not load system trusted ca certificates: "
+              << ERR_error_string(ERR_get_error(), nullptr);
+  }
+
+  if (!tlsconf.cacert.empty()) {
+    if (SSL_CTX_load_verify_locations(ssl_ctx, tlsconf.cacert.c_str(),
+                                      nullptr) != 1) {
+      LOG(FATAL) << "Could not load trusted ca certificates from "
+                 << tlsconf.cacert << ": "
+                 << ERR_error_string(ERR_get_error(), nullptr);
+      DIE();
+    }
+  }
+
+  if (!tlsconf.private_key_passwd.empty()) {
+    SSL_CTX_set_default_passwd_cb(ssl_ctx, ssl_pem_passwd_cb);
+    SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, config);
+  }
+
+#  ifndef HAVE_NEVERBLEED
+  if (SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key_file,
+                                  SSL_FILETYPE_PEM) != 1) {
+    LOG(FATAL) << "SSL_CTX_use_PrivateKey_file failed: "
+               << ERR_error_string(ERR_get_error(), nullptr);
+  }
+#  else  // HAVE_NEVERBLEED
+  std::array<char, NEVERBLEED_ERRBUF_SIZE> errbuf;
+  if (neverbleed_load_private_key_file(nb, ssl_ctx, private_key_file,
+                                       errbuf.data()) != 1) {
+    LOG(FATAL) << "neverbleed_load_private_key_file failed: " << errbuf.data();
+    DIE();
+  }
+#  endif // HAVE_NEVERBLEED
+
+  if (SSL_CTX_use_certificate_chain_file(ssl_ctx, cert_file) != 1) {
+    LOG(FATAL) << "SSL_CTX_use_certificate_file failed: "
+               << ERR_error_string(ERR_get_error(), nullptr);
+    DIE();
+  }
+  if (SSL_CTX_check_private_key(ssl_ctx) != 1) {
+    LOG(FATAL) << "SSL_CTX_check_private_key failed: "
+               << ERR_error_string(ERR_get_error(), nullptr);
+    DIE();
+  }
+  if (tlsconf.client_verify.enabled) {
+    if (!tlsconf.client_verify.cacert.empty()) {
+      if (SSL_CTX_load_verify_locations(
+              ssl_ctx, tlsconf.client_verify.cacert.c_str(), nullptr) != 1) {
+
+        LOG(FATAL) << "Could not load trusted ca certificates from "
+                   << tlsconf.client_verify.cacert << ": "
+                   << ERR_error_string(ERR_get_error(), nullptr);
+        DIE();
+      }
+      // It is heard that SSL_CTX_load_verify_locations() may leave
+      // error even though it returns success. See
+      // http://forum.nginx.org/read.php?29,242540
+      ERR_clear_error();
+      auto list = SSL_load_client_CA_file(tlsconf.client_verify.cacert.c_str());
+      if (!list) {
+        LOG(FATAL) << "Could not load ca certificates from "
+                   << tlsconf.client_verify.cacert << ": "
+                   << ERR_error_string(ERR_get_error(), nullptr);
+        DIE();
+      }
+      SSL_CTX_set_client_CA_list(ssl_ctx, list);
+    }
+    SSL_CTX_set_verify(ssl_ctx,
+                       SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE |
+                           SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+                       verify_callback);
+  }
+  SSL_CTX_set_tlsext_servername_callback(ssl_ctx, servername_callback);
+#  if OPENSSL_3_0_0_API
+  SSL_CTX_set_tlsext_ticket_key_evp_cb(ssl_ctx, ticket_key_cb);
+#  else  // !OPENSSL_3_0_0_API
+  SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx, ticket_key_cb);
+#  endif // !OPENSSL_3_0_0_API
+#  ifndef OPENSSL_IS_BORINGSSL
+  SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb);
+#  endif // OPENSSL_IS_BORINGSSL
+
+#  if OPENSSL_VERSION_NUMBER >= 0x10002000L
+  // ALPN selection callback
+  SSL_CTX_set_alpn_select_cb(ssl_ctx, quic_alpn_select_proto_cb, nullptr);
+#  endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
+
   auto tls_ctx_data = new TLSContextData();
   tls_ctx_data->cert_file = cert_file;
   tls_ctx_data->sct_data = sct_data;
 
   SSL_CTX_set_app_data(ssl_ctx, tls_ctx_data);
 
+#  if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L &&             \
+      !defined(OPENSSL_IS_BORINGSSL)
+  // SSL_extension_supported(TLSEXT_TYPE_signed_certificate_timestamp)
+  // returns 1, which means OpenSSL internally handles it.  But
+  // OpenSSL handles signed_certificate_timestamp extension specially,
+  // and it lets custom handler to process the extension.
+  if (!sct_data.empty()) {
+#    if OPENSSL_1_1_1_API
+    // It is not entirely clear to me that SSL_EXT_CLIENT_HELLO is
+    // required here.  sct_parse_cb is called without
+    // SSL_EXT_CLIENT_HELLO being set.  But the passed context value
+    // is SSL_EXT_CLIENT_HELLO.
+    if (SSL_CTX_add_custom_ext(
+            ssl_ctx, TLSEXT_TYPE_signed_certificate_timestamp,
+            SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO |
+                SSL_EXT_TLS1_3_CERTIFICATE | SSL_EXT_IGNORE_ON_RESUMPTION,
+            sct_add_cb, sct_free_cb, nullptr, sct_parse_cb, nullptr) != 1) {
+      LOG(FATAL) << "SSL_CTX_add_custom_ext failed: "
+                 << ERR_error_string(ERR_get_error(), nullptr);
+      DIE();
+    }
+#    else  // !OPENSSL_1_1_1_API
+    if (SSL_CTX_add_server_custom_ext(
+            ssl_ctx, TLSEXT_TYPE_signed_certificate_timestamp,
+            legacy_sct_add_cb, legacy_sct_free_cb, nullptr, legacy_sct_parse_cb,
+            nullptr) != 1) {
+      LOG(FATAL) << "SSL_CTX_add_server_custom_ext failed: "
+                 << ERR_error_string(ERR_get_error(), nullptr);
+      DIE();
+    }
+#    endif // !OPENSSL_1_1_1_API
+  }
+#  elif defined(OPENSSL_IS_BORINGSSL)
+  if (!tls_ctx_data->sct_data.empty() &&
+      SSL_CTX_set_signed_cert_timestamp_list(
+          ssl_ctx, tls_ctx_data->sct_data.data(),
+          tls_ctx_data->sct_data.size()) != 1) {
+    LOG(FATAL) << "SSL_CTX_set_signed_cert_timestamp_list failed: "
+               << ERR_error_string(ERR_get_error(), nullptr);
+    DIE();
+  }
+#  endif // defined(OPENSSL_IS_BORINGSSL)
+
+#  if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+  auto &quicconf = config->quic;
+
+  if (quicconf.upstream.early_data &&
+      SSL_CTX_set_max_early_data(ssl_ctx,
+                                 std::numeric_limits<uint32_t>::max()) != 1) {
+    LOG(FATAL) << "SSL_CTX_set_max_early_data failed: "
+               << ERR_error_string(ERR_get_error(), nullptr);
+    DIE();
+  }
+#  endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
+
+#  ifndef OPENSSL_NO_PSK
+  SSL_CTX_set_psk_server_callback(ssl_ctx, psk_server_cb);
+#  endif // !LIBRESSL_NO_PSK
+
+  SSL_CTX_set_quic_method(ssl_ctx, &quic_method);
+
   return ssl_ctx;
 }
+#endif // ENABLE_HTTP3
 
 namespace {
 int select_h2_next_proto_cb(SSL *ssl, unsigned char **out,
@@ -1073,7 +1694,7 @@ SSL_CTX *create_ssl_client_context(
     int (*next_proto_select_cb)(SSL *s, unsigned char **out,
                                 unsigned char *outlen, const unsigned char *in,
                                 unsigned int inlen, void *arg)) {
-  auto ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+  auto ssl_ctx = SSL_CTX_new(TLS_client_method());
   if (!ssl_ctx) {
     LOG(FATAL) << ERR_error_string(ERR_get_error(), nullptr);
     DIE();
@@ -1104,14 +1725,14 @@ SSL_CTX *create_ssl_client_context(
     DIE();
   }
 
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
   if (SSL_CTX_set_ciphersuites(ssl_ctx, tlsconf.client.tls13_ciphers.c_str()) ==
       0) {
     LOG(FATAL) << "SSL_CTX_set_ciphersuites " << tlsconf.client.tls13_ciphers
                << " failed: " << ERR_error_string(ERR_get_error(), nullptr);
     DIE();
   }
-#endif // OPENSSL_1_1_1_API
+#endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
 
   SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
 
@@ -1449,14 +2070,20 @@ int verify_hostname(X509 *cert, const StringRef &hostname,
 } // namespace
 
 int check_cert(SSL *ssl, const Address *addr, const StringRef &host) {
+#if OPENSSL_3_0_0_API
+  auto cert = SSL_get0_peer_certificate(ssl);
+#else  // !OPENSSL_3_0_0_API
   auto cert = SSL_get_peer_certificate(ssl);
+#endif // !OPENSSL_3_0_0_API
   if (!cert) {
     // By the protocol definition, TLS server always sends certificate
     // if it has.  If certificate cannot be retrieved, authentication
     // without certificate is used, such as PSK.
     return 0;
   }
+#if !OPENSSL_3_0_0_API
   auto cert_deleter = defer(X509_free, cert);
+#endif // !OPENSSL_3_0_0_API
 
   if (verify_hostname(cert, host, addr) != 0) {
     LOG(ERROR) << "Certificate verification failed: hostname does not match";
@@ -1722,6 +2349,12 @@ bool in_proto_list(const std::vector<StringRef> &protos,
 }
 
 bool upstream_tls_enabled(const ConnectionConfig &connconf) {
+#ifdef ENABLE_HTTP3
+  if (connconf.quic_listener.addrs.size()) {
+    return true;
+  }
+#endif // ENABLE_HTTP3
+
   const auto &faddrs = connconf.listener.addrs;
   return std::any_of(std::begin(faddrs), std::end(faddrs),
                      [](const UpstreamAddr &faddr) { return faddr.tls; });
@@ -1801,6 +2434,63 @@ setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
   return ssl_ctx;
 }
 
+#ifdef ENABLE_HTTP3
+SSL_CTX *setup_quic_server_ssl_context(
+    std::vector<SSL_CTX *> &all_ssl_ctx,
+    std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
+    CertLookupTree *cert_tree
+#  ifdef HAVE_NEVERBLEED
+    ,
+    neverbleed_t *nb
+#  endif // HAVE_NEVERBLEED
+) {
+  auto config = get_config();
+
+  if (!upstream_tls_enabled(config->conn)) {
+    return nullptr;
+  }
+
+  auto &tlsconf = config->tls;
+
+  auto ssl_ctx =
+      create_quic_ssl_context(tlsconf.private_key_file.c_str(),
+                              tlsconf.cert_file.c_str(), tlsconf.sct_data
+#  ifdef HAVE_NEVERBLEED
+                              ,
+                              nb
+#  endif // HAVE_NEVERBLEED
+      );
+
+  all_ssl_ctx.push_back(ssl_ctx);
+
+  assert(cert_tree);
+
+  if (cert_lookup_tree_add_ssl_ctx(cert_tree, indexed_ssl_ctx, ssl_ctx) == -1) {
+    LOG(FATAL) << "Failed to add default certificate.";
+    DIE();
+  }
+
+  for (auto &c : tlsconf.subcerts) {
+    auto ssl_ctx = create_quic_ssl_context(c.private_key_file.c_str(),
+                                           c.cert_file.c_str(), c.sct_data
+#  ifdef HAVE_NEVERBLEED
+                                           ,
+                                           nb
+#  endif // HAVE_NEVERBLEED
+    );
+    all_ssl_ctx.push_back(ssl_ctx);
+
+    if (cert_lookup_tree_add_ssl_ctx(cert_tree, indexed_ssl_ctx, ssl_ctx) ==
+        -1) {
+      LOG(FATAL) << "Failed to add sub certificate.";
+      DIE();
+    }
+  }
+
+  return ssl_ctx;
+}
+#endif // ENABLE_HTTP3
+
 SSL_CTX *setup_downstream_client_ssl_context(
 #ifdef HAVE_NEVERBLEED
     neverbleed_t *nb
@@ -2050,7 +2740,7 @@ namespace {
 int time_t_from_asn1_time(time_t &t, const ASN1_TIME *at) {
   int rv;
 
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
   struct tm tm;
   rv = ASN1_TIME_to_tm(at, &tm);
   if (rv != 1) {
@@ -2058,7 +2748,7 @@ int time_t_from_asn1_time(time_t &t, const ASN1_TIME *at) {
   }
 
   t = nghttp2_timegm(&tm);
-#else // !OPENSSL_1_1_1_API
+#else // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
   auto b = BIO_new(BIO_s_mem());
   if (!b) {
     return -1;
@@ -2071,7 +2761,7 @@ int time_t_from_asn1_time(time_t &t, const ASN1_TIME *at) {
     return -1;
   }
 
-#  if defined(OPENSSL_IS_BORINGSSL)
+#  ifdef OPENSSL_IS_BORINGSSL
   char *s;
 #  else
   unsigned char *s;
@@ -2084,7 +2774,7 @@ int time_t_from_asn1_time(time_t &t, const ASN1_TIME *at) {
   }
 
   t = tt;
-#endif // !OPENSSL_1_1_1_API
+#endif // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
 
   return 0;
 }
index 1ca2033..5d751c0 100644 (file)
@@ -100,6 +100,18 @@ SSL_CTX *create_ssl_client_context(
                                 unsigned char *outlen, const unsigned char *in,
                                 unsigned int inlen, void *arg));
 
+#ifdef ENABLE_HTTP3
+SSL_CTX *create_quic_ssl_client_context(
+#  ifdef HAVE_NEVERBLEED
+    neverbleed_t *nb,
+#  endif // HAVE_NEVERBLEED
+    const StringRef &cacert, const StringRef &cert_file,
+    const StringRef &private_key_file,
+    int (*next_proto_select_cb)(SSL *s, unsigned char **out,
+                                unsigned char *outlen, const unsigned char *in,
+                                unsigned int inlen, void *arg));
+#endif // ENABLE_HTTP3
+
 ClientHandler *accept_connection(Worker *worker, int fd, sockaddr *addr,
                                  int addrlen, const UpstreamAddr *faddr);
 
@@ -217,6 +229,18 @@ setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
 #endif // HAVE_NEVERBLEED
 );
 
+#ifdef ENABLE_HTTP3
+SSL_CTX *setup_quic_server_ssl_context(
+    std::vector<SSL_CTX *> &all_ssl_ctx,
+    std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
+    CertLookupTree *cert_tree
+#  ifdef HAVE_NEVERBLEED
+    ,
+    neverbleed_t *nb
+#  endif // HAVE_NEVERBLEED
+);
+#endif // ENABLE_HTTP3
+
 // Setups client side SSL_CTX.
 SSL_CTX *setup_downstream_client_ssl_context(
 #ifdef HAVE_NEVERBLEED
index 0f130f6..ef80a1a 100644 (file)
@@ -121,7 +121,7 @@ void test_shrpx_tls_cert_lookup_tree_add_ssl_ctx(void) {
 
   static constexpr char nghttp2_certfile[] =
       NGHTTP2_SRC_DIR "/test.nghttp2.org.pem";
-  auto nghttp2_ssl_ctx = SSL_CTX_new(SSLv23_server_method());
+  auto nghttp2_ssl_ctx = SSL_CTX_new(TLS_server_method());
   auto nghttp2_ssl_ctx_del = defer(SSL_CTX_free, nghttp2_ssl_ctx);
   auto nghttp2_tls_ctx_data = std::make_unique<tls::TLSContextData>();
   nghttp2_tls_ctx_data->cert_file = nghttp2_certfile;
@@ -132,7 +132,7 @@ void test_shrpx_tls_cert_lookup_tree_add_ssl_ctx(void) {
 
   static constexpr char examples_certfile[] =
       NGHTTP2_SRC_DIR "/test.example.com.pem";
-  auto examples_ssl_ctx = SSL_CTX_new(SSLv23_server_method());
+  auto examples_ssl_ctx = SSL_CTX_new(TLS_server_method());
   auto examples_ssl_ctx_del = defer(SSL_CTX_free, examples_ssl_ctx);
   auto examples_tls_ctx_data = std::make_unique<tls::TLSContextData>();
   examples_tls_ctx_data->cert_file = examples_certfile;
index cc0254d..a0107cc 100644 (file)
 #  include <unistd.h>
 #endif // HAVE_UNISTD_H
 
+#include <cstdio>
 #include <memory>
 
+#include <openssl/rand.h>
+
+#ifdef HAVE_LIBBPF
+#  include <bpf/bpf.h>
+#  include <bpf/libbpf.h>
+#endif // HAVE_LIBBPF
+
 #include "shrpx_tls.h"
 #include "shrpx_log.h"
 #include "shrpx_client_handler.h"
 #ifdef HAVE_MRUBY
 #  include "shrpx_mruby.h"
 #endif // HAVE_MRUBY
+#ifdef ENABLE_HTTP3
+#  include "shrpx_quic_listener.h"
+#endif // ENABLE_HTTP3
+#include "shrpx_connection_handler.h"
 #include "util.h"
 #include "template.h"
+#include "xsi_strerror.h"
 
 namespace shrpx {
 
@@ -57,7 +70,10 @@ void mcpool_clear_cb(struct ev_loop *loop, ev_timer *w, int revents) {
   if (worker->get_worker_stat()->num_connections != 0) {
     return;
   }
-  worker->get_mcpool()->clear();
+  auto mcpool = worker->get_mcpool();
+  if (mcpool->freelistsize == mcpool->poolsize) {
+    worker->get_mcpool()->clear();
+  }
 }
 } // namespace
 
@@ -79,7 +95,7 @@ using DownstreamKey =
                                       size_t, Proto, uint32_t, uint32_t,
                                       uint32_t, bool, bool, bool, bool>>,
                bool, SessionAffinity, StringRef, StringRef,
-               SessionAffinityCookieSecure, int64_t, int64_t, StringRef>;
+               SessionAffinityCookieSecure, int64_t, int64_t, StringRef, bool>;
 
 namespace {
 DownstreamKey
@@ -119,6 +135,7 @@ create_downstream_key(const std::shared_ptr<SharedDownstreamAddr> &shared_addr,
   std::get<6>(dkey) = timeout.read;
   std::get<7>(dkey) = timeout.write;
   std::get<8>(dkey) = mruby_file;
+  std::get<9>(dkey) = shared_addr->dnf;
 
   return dkey;
 }
@@ -127,21 +144,44 @@ create_downstream_key(const std::shared_ptr<SharedDownstreamAddr> &shared_addr,
 Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
                SSL_CTX *tls_session_cache_memcached_ssl_ctx,
                tls::CertLookupTree *cert_tree,
+#ifdef ENABLE_HTTP3
+               SSL_CTX *quic_sv_ssl_ctx, tls::CertLookupTree *quic_cert_tree,
+               const uint8_t *cid_prefix, size_t cid_prefixlen,
+#  ifdef HAVE_LIBBPF
+               size_t index,
+#  endif // HAVE_LIBBPF
+#endif   // ENABLE_HTTP3
                const std::shared_ptr<TicketKeys> &ticket_keys,
                ConnectionHandler *conn_handler,
                std::shared_ptr<DownstreamConfig> downstreamconf)
-    : randgen_(util::make_mt19937()),
+    :
+#if defined(ENABLE_HTTP3) && defined(HAVE_LIBBPF)
+      index_{index},
+#endif // ENABLE_HTTP3 && HAVE_LIBBPF
+      randgen_(util::make_mt19937()),
       worker_stat_{},
       dns_tracker_(loop),
+#ifdef ENABLE_HTTP3
+      quic_upstream_addrs_{get_config()->conn.quic_listener.addrs},
+#endif // ENABLE_HTTP3
       loop_(loop),
       sv_ssl_ctx_(sv_ssl_ctx),
       cl_ssl_ctx_(cl_ssl_ctx),
       cert_tree_(cert_tree),
       conn_handler_(conn_handler),
+#ifdef ENABLE_HTTP3
+      quic_sv_ssl_ctx_{quic_sv_ssl_ctx},
+      quic_cert_tree_{quic_cert_tree},
+      quic_conn_handler_{this},
+#endif // ENABLE_HTTP3
       ticket_keys_(ticket_keys),
       connect_blocker_(
           std::make_unique<ConnectBlocker>(randgen_, loop_, nullptr, nullptr)),
       graceful_shutdown_(false) {
+#ifdef ENABLE_HTTP3
+  std::copy_n(cid_prefix, cid_prefixlen, std::begin(cid_prefix_));
+#endif // ENABLE_HTTP3
+
   ev_async_init(&w_, eventcb);
   w_.data = this;
   ev_async_start(loop_, &w_);
@@ -249,6 +289,7 @@ void Worker::replace_downstream_config(
     }
     shared_addr->affinity_hash = src.affinity_hash;
     shared_addr->redirect_if_not_tls = src.redirect_if_not_tls;
+    shared_addr->dnf = src.dnf;
     shared_addr->timeout.read = src.timeout.read;
     shared_addr->timeout.write = src.timeout.write;
 
@@ -272,21 +313,6 @@ void Worker::replace_downstream_config(
       dst_addr.rise = src_addr.rise;
       dst_addr.dns = src_addr.dns;
       dst_addr.upgrade_scheme = src_addr.upgrade_scheme;
-
-      auto shared_addr_ptr = shared_addr.get();
-
-      dst_addr.connect_blocker = std::make_unique<ConnectBlocker>(
-          randgen_, loop_, nullptr, [shared_addr_ptr, &dst_addr]() {
-            if (!dst_addr.queued) {
-              if (!dst_addr.wg) {
-                return;
-              }
-              ensure_enqueue_addr(shared_addr_ptr->pq, dst_addr.wg, &dst_addr);
-            }
-          });
-
-      dst_addr.live_check = std::make_unique<LiveCheck>(
-          loop_, cl_ssl_ctx_, this, &dst_addr, randgen_);
     }
 
 #ifdef HAVE_MRUBY
@@ -310,6 +336,23 @@ void Worker::replace_downstream_config(
       std::shuffle(std::begin(shared_addr->addrs), std::end(shared_addr->addrs),
                    randgen_);
 
+      auto shared_addr_ptr = shared_addr.get();
+
+      for (auto &addr : shared_addr->addrs) {
+        addr.connect_blocker = std::make_unique<ConnectBlocker>(
+            randgen_, loop_, nullptr, [shared_addr_ptr, &addr]() {
+              if (!addr.queued) {
+                if (!addr.wg) {
+                  return;
+                }
+                ensure_enqueue_addr(shared_addr_ptr->pq, addr.wg, &addr);
+              }
+            });
+
+        addr.live_check = std::make_unique<LiveCheck>(loop_, cl_ssl_ctx_, this,
+                                                      &addr, randgen_);
+      }
+
       size_t seq = 0;
       for (auto &addr : shared_addr->addrs) {
         addr.dconn_pool = std::make_unique<DownstreamConnectionPool>();
@@ -393,11 +436,11 @@ void Worker::run_async() {
 #endif // !NOTHREADS
 }
 
-void Worker::send(const WorkerEvent &event) {
+void Worker::send(WorkerEvent event) {
   {
     std::lock_guard<std::mutex> g(m_);
 
-    q_.push_back(event);
+    q_.emplace_back(std::move(event));
   }
 
   ev_async_send(loop_, &w_);
@@ -418,7 +461,7 @@ void Worker::process_events() {
       return;
     }
 
-    wev = q_.front();
+    wev = std::move(q_.front());
     q_.pop_front();
   }
 
@@ -475,7 +518,8 @@ void Worker::process_events() {
 
     graceful_shutdown_ = true;
 
-    if (worker_stat_.num_connections == 0) {
+    if (worker_stat_.num_connections == 0 &&
+        worker_stat_.num_close_waits == 0) {
       ev_break(loop_);
 
       return;
@@ -488,6 +532,33 @@ void Worker::process_events() {
     replace_downstream_config(wev.downstreamconf);
 
     break;
+#ifdef ENABLE_HTTP3
+  case WorkerEventType::QUIC_PKT_FORWARD: {
+    const UpstreamAddr *faddr;
+
+    if (wev.quic_pkt->upstream_addr_index == static_cast<size_t>(-1)) {
+      faddr = find_quic_upstream_addr(wev.quic_pkt->local_addr);
+      if (faddr == nullptr) {
+        LOG(ERROR) << "No suitable upstream address found";
+
+        break;
+      }
+    } else if (quic_upstream_addrs_.size() <=
+               wev.quic_pkt->upstream_addr_index) {
+      LOG(ERROR) << "upstream_addr_index is too large";
+
+      break;
+    } else {
+      faddr = &quic_upstream_addrs_[wev.quic_pkt->upstream_addr_index];
+    }
+
+    quic_conn_handler_.handle_packet(
+        faddr, wev.quic_pkt->remote_addr, wev.quic_pkt->local_addr,
+        wev.quic_pkt->data.data(), wev.quic_pkt->data.size());
+
+    break;
+  }
+#endif // ENABLE_HTTP3
   default:
     if (LOG_ENABLED(INFO)) {
       WLOG(INFO, this) << "unknown event type " << static_cast<int>(wev.type);
@@ -497,6 +568,12 @@ void Worker::process_events() {
 
 tls::CertLookupTree *Worker::get_cert_lookup_tree() const { return cert_tree_; }
 
+#ifdef ENABLE_HTTP3
+tls::CertLookupTree *Worker::get_quic_cert_lookup_tree() const {
+  return quic_cert_tree_;
+}
+#endif // ENABLE_HTTP3
+
 std::shared_ptr<TicketKeys> Worker::get_ticket_keys() {
 #ifdef HAVE_ATOMIC_STD_SHARED_PTR
   return std::atomic_load_explicit(&ticket_keys_, std::memory_order_acquire);
@@ -527,6 +604,10 @@ SSL_CTX *Worker::get_sv_ssl_ctx() const { return sv_ssl_ctx_; }
 
 SSL_CTX *Worker::get_cl_ssl_ctx() const { return cl_ssl_ctx_; }
 
+#ifdef ENABLE_HTTP3
+SSL_CTX *Worker::get_quic_sv_ssl_ctx() const { return quic_sv_ssl_ctx_; }
+#endif // ENABLE_HTTP3
+
 void Worker::set_graceful_shutdown(bool f) { graceful_shutdown_ = f; }
 
 bool Worker::get_graceful_shutdown() const { return graceful_shutdown_; }
@@ -571,8 +652,450 @@ ConnectionHandler *Worker::get_connection_handler() const {
   return conn_handler_;
 }
 
+#ifdef ENABLE_HTTP3
+QUICConnectionHandler *Worker::get_quic_connection_handler() {
+  return &quic_conn_handler_;
+}
+#endif // ENABLE_HTTP3
+
 DNSTracker *Worker::get_dns_tracker() { return &dns_tracker_; }
 
+#ifdef ENABLE_HTTP3
+#  ifdef HAVE_LIBBPF
+bool Worker::should_attach_bpf() const {
+  auto config = get_config();
+  auto &quicconf = config->quic;
+  auto &apiconf = config->api;
+
+  if (quicconf.bpf.disabled) {
+    return false;
+  }
+
+  if (!config->single_thread && apiconf.enabled) {
+    return index_ == 1;
+  }
+
+  return index_ == 0;
+}
+
+bool Worker::should_update_bpf_map() const {
+  auto config = get_config();
+  auto &quicconf = config->quic;
+
+  return !quicconf.bpf.disabled;
+}
+
+uint32_t Worker::compute_sk_index() const {
+  auto config = get_config();
+  auto &apiconf = config->api;
+
+  if (!config->single_thread && apiconf.enabled) {
+    return index_ - 1;
+  }
+
+  return index_;
+}
+#  endif // HAVE_LIBBPF
+
+int Worker::setup_quic_server_socket() {
+  size_t n = 0;
+
+  for (auto &addr : quic_upstream_addrs_) {
+    assert(!addr.host_unix);
+    if (create_quic_server_socket(addr) != 0) {
+      return -1;
+    }
+
+    // Make sure that each endpoint has a unique address.
+    for (size_t i = 0; i < n; ++i) {
+      const auto &a = quic_upstream_addrs_[i];
+
+      if (addr.hostport == a.hostport) {
+        LOG(FATAL)
+            << "QUIC frontend endpoint must be unique: a duplicate found for "
+            << addr.hostport;
+
+        return -1;
+      }
+    }
+
+    ++n;
+
+    quic_listeners_.emplace_back(std::make_unique<QUICListener>(&addr, this));
+  }
+
+  return 0;
+}
+
+int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
+  std::array<char, STRERROR_BUFSIZE> errbuf;
+  int fd = -1;
+  int rv;
+
+  auto service = util::utos(faddr.port);
+  addrinfo hints{};
+  hints.ai_family = faddr.family;
+  hints.ai_socktype = SOCK_DGRAM;
+  hints.ai_flags = AI_PASSIVE;
+#  ifdef AI_ADDRCONFIG
+  hints.ai_flags |= AI_ADDRCONFIG;
+#  endif // AI_ADDRCONFIG
+
+  auto node =
+      faddr.host == StringRef::from_lit("*") ? nullptr : faddr.host.c_str();
+
+  addrinfo *res, *rp;
+  rv = getaddrinfo(node, service.c_str(), &hints, &res);
+#  ifdef AI_ADDRCONFIG
+  if (rv != 0) {
+    // Retry without AI_ADDRCONFIG
+    hints.ai_flags &= ~AI_ADDRCONFIG;
+    rv = getaddrinfo(node, service.c_str(), &hints, &res);
+  }
+#  endif // AI_ADDRCONFIG
+  if (rv != 0) {
+    LOG(FATAL) << "Unable to get IPv" << (faddr.family == AF_INET ? "4" : "6")
+               << " address for " << faddr.host << ", port " << faddr.port
+               << ": " << gai_strerror(rv);
+    return -1;
+  }
+
+  auto res_d = defer(freeaddrinfo, res);
+
+  std::array<char, NI_MAXHOST> host;
+
+  for (rp = res; rp; rp = rp->ai_next) {
+    rv = getnameinfo(rp->ai_addr, rp->ai_addrlen, host.data(), host.size(),
+                     nullptr, 0, NI_NUMERICHOST);
+    if (rv != 0) {
+      LOG(WARN) << "getnameinfo() failed: " << gai_strerror(rv);
+      continue;
+    }
+
+#  ifdef SOCK_NONBLOCK
+    fd = socket(rp->ai_family, rp->ai_socktype | SOCK_NONBLOCK | SOCK_CLOEXEC,
+                rp->ai_protocol);
+    if (fd == -1) {
+      auto error = errno;
+      LOG(WARN) << "socket() syscall failed: "
+                << xsi_strerror(error, errbuf.data(), errbuf.size());
+      continue;
+    }
+#  else  // !SOCK_NONBLOCK
+    fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+    if (fd == -1) {
+      auto error = errno;
+      LOG(WARN) << "socket() syscall failed: "
+                << xsi_strerror(error, errbuf.data(), errbuf.size());
+      continue;
+    }
+    util::make_socket_nonblocking(fd);
+    util::make_socket_closeonexec(fd);
+#  endif // !SOCK_NONBLOCK
+
+    int val = 1;
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
+                   static_cast<socklen_t>(sizeof(val))) == -1) {
+      auto error = errno;
+      LOG(WARN) << "Failed to set SO_REUSEADDR option to listener socket: "
+                << xsi_strerror(error, errbuf.data(), errbuf.size());
+      close(fd);
+      continue;
+    }
+
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val,
+                   static_cast<socklen_t>(sizeof(val))) == -1) {
+      auto error = errno;
+      LOG(WARN) << "Failed to set SO_REUSEPORT option to listener socket: "
+                << xsi_strerror(error, errbuf.data(), errbuf.size());
+      close(fd);
+      continue;
+    }
+
+    if (faddr.family == AF_INET6) {
+#  ifdef IPV6_V6ONLY
+      if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
+                     static_cast<socklen_t>(sizeof(val))) == -1) {
+        auto error = errno;
+        LOG(WARN) << "Failed to set IPV6_V6ONLY option to listener socket: "
+                  << xsi_strerror(error, errbuf.data(), errbuf.size());
+        close(fd);
+        continue;
+      }
+#  endif // IPV6_V6ONLY
+
+      if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val,
+                     static_cast<socklen_t>(sizeof(val))) == -1) {
+        auto error = errno;
+        LOG(WARN)
+            << "Failed to set IPV6_RECVPKTINFO option to listener socket: "
+            << xsi_strerror(error, errbuf.data(), errbuf.size());
+        close(fd);
+        continue;
+      }
+    } else {
+      if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &val,
+                     static_cast<socklen_t>(sizeof(val))) == -1) {
+        auto error = errno;
+        LOG(WARN) << "Failed to set IP_PKTINFO option to listener socket: "
+                  << xsi_strerror(error, errbuf.data(), errbuf.size());
+        close(fd);
+        continue;
+      }
+    }
+
+    // TODO Enable ECN
+
+    if (bind(fd, rp->ai_addr, rp->ai_addrlen) == -1) {
+      auto error = errno;
+      LOG(WARN) << "bind() syscall failed: "
+                << xsi_strerror(error, errbuf.data(), errbuf.size());
+      close(fd);
+      continue;
+    }
+
+#  ifdef HAVE_LIBBPF
+    auto config = get_config();
+
+    auto &quic_bpf_refs = conn_handler_->get_quic_bpf_refs();
+    int err;
+
+    if (should_attach_bpf()) {
+      auto &bpfconf = config->quic.bpf;
+
+      auto obj = bpf_object__open_file(bpfconf.prog_file.c_str(), nullptr);
+      err = libbpf_get_error(obj);
+      if (err) {
+        LOG(FATAL) << "Failed to open bpf object file: "
+                   << xsi_strerror(-err, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+
+      if (bpf_object__load(obj)) {
+        LOG(FATAL) << "Failed to load bpf object file: "
+                   << xsi_strerror(errno, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+
+      auto prog = bpf_object__find_program_by_name(obj, "select_reuseport");
+      err = libbpf_get_error(prog);
+      if (err) {
+        LOG(FATAL) << "Failed to find sk_reuseport program: "
+                   << xsi_strerror(-err, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+
+      auto &ref = quic_bpf_refs[faddr.index];
+
+      ref.obj = obj;
+
+      auto reuseport_array =
+          bpf_object__find_map_by_name(obj, "reuseport_array");
+      err = libbpf_get_error(reuseport_array);
+      if (err) {
+        LOG(FATAL) << "Failed to get reuseport_array: "
+                   << xsi_strerror(-err, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+
+      ref.reuseport_array = bpf_map__fd(reuseport_array);
+
+      auto cid_prefix_map = bpf_object__find_map_by_name(obj, "cid_prefix_map");
+      err = libbpf_get_error(cid_prefix_map);
+      if (err) {
+        LOG(FATAL) << "Failed to get cid_prefix_map: "
+                   << xsi_strerror(-err, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+
+      ref.cid_prefix_map = bpf_map__fd(cid_prefix_map);
+
+      auto sk_info = bpf_object__find_map_by_name(obj, "sk_info");
+      err = libbpf_get_error(sk_info);
+      if (err) {
+        LOG(FATAL) << "Failed to get sk_info: "
+                   << xsi_strerror(-err, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+
+      constexpr uint32_t zero = 0;
+      uint64_t num_socks = config->num_worker;
+
+      if (bpf_map_update_elem(bpf_map__fd(sk_info), &zero, &num_socks,
+                              BPF_ANY) != 0) {
+        LOG(FATAL) << "Failed to update sk_info: "
+                   << xsi_strerror(errno, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+
+      constexpr uint32_t key_high_idx = 1;
+      constexpr uint32_t key_low_idx = 2;
+
+      auto &qkms = conn_handler_->get_quic_keying_materials();
+      auto &qkm = qkms->keying_materials.front();
+
+      if (bpf_map_update_elem(bpf_map__fd(sk_info), &key_high_idx,
+                              qkm.cid_encryption_key.data(), BPF_ANY) != 0) {
+        LOG(FATAL) << "Failed to update key_high_idx sk_info: "
+                   << xsi_strerror(errno, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+
+      if (bpf_map_update_elem(bpf_map__fd(sk_info), &key_low_idx,
+                              qkm.cid_encryption_key.data() + 8,
+                              BPF_ANY) != 0) {
+        LOG(FATAL) << "Failed to update key_low_idx sk_info: "
+                   << xsi_strerror(errno, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+
+      auto prog_fd = bpf_program__fd(prog);
+
+      if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF, &prog_fd,
+                     static_cast<socklen_t>(sizeof(prog_fd))) == -1) {
+        LOG(FATAL) << "Failed to attach bpf program: "
+                   << xsi_strerror(errno, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+    }
+
+    if (should_update_bpf_map()) {
+      const auto &ref = quic_bpf_refs[faddr.index];
+      auto sk_index = compute_sk_index();
+
+      if (bpf_map_update_elem(ref.reuseport_array, &sk_index, &fd,
+                              BPF_NOEXIST) != 0) {
+        LOG(FATAL) << "Failed to update reuseport_array: "
+                   << xsi_strerror(errno, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+
+      if (bpf_map_update_elem(ref.cid_prefix_map, cid_prefix_.data(), &sk_index,
+                              BPF_NOEXIST) != 0) {
+        LOG(FATAL) << "Failed to update cid_prefix_map: "
+                   << xsi_strerror(errno, errbuf.data(), errbuf.size());
+        close(fd);
+        return -1;
+      }
+    }
+#  endif // HAVE_LIBBPF
+
+    break;
+  }
+
+  if (!rp) {
+    LOG(FATAL) << "Listening " << (faddr.family == AF_INET ? "IPv4" : "IPv6")
+               << " socket failed";
+
+    return -1;
+  }
+
+  faddr.fd = fd;
+  faddr.hostport = util::make_http_hostport(mod_config()->balloc,
+                                            StringRef{host.data()}, faddr.port);
+
+  LOG(NOTICE) << "Listening on " << faddr.hostport << ", quic";
+
+  return 0;
+}
+
+const uint8_t *Worker::get_cid_prefix() const { return cid_prefix_.data(); }
+
+const UpstreamAddr *Worker::find_quic_upstream_addr(const Address &local_addr) {
+  std::array<char, NI_MAXHOST> host;
+
+  auto rv = getnameinfo(&local_addr.su.sa, local_addr.len, host.data(),
+                        host.size(), nullptr, 0, NI_NUMERICHOST);
+  if (rv != 0) {
+    LOG(ERROR) << "getnameinfo: " << gai_strerror(rv);
+
+    return nullptr;
+  }
+
+  uint16_t port;
+
+  switch (local_addr.su.sa.sa_family) {
+  case AF_INET:
+    port = htons(local_addr.su.in.sin_port);
+
+    break;
+  case AF_INET6:
+    port = htons(local_addr.su.in6.sin6_port);
+
+    break;
+  default:
+    assert(0);
+    abort();
+  }
+
+  std::array<char, util::max_hostport> hostport_buf;
+
+  auto hostport = util::make_http_hostport(std::begin(hostport_buf),
+                                           StringRef{host.data()}, port);
+  const UpstreamAddr *fallback_faddr = nullptr;
+
+  for (auto &faddr : quic_upstream_addrs_) {
+    if (faddr.hostport == hostport) {
+      return &faddr;
+    }
+
+    if (faddr.port != port || faddr.family != local_addr.su.sa.sa_family) {
+      continue;
+    }
+
+    if (faddr.port == 443 || faddr.port == 80) {
+      switch (faddr.family) {
+      case AF_INET:
+        if (util::streq(faddr.hostport, StringRef::from_lit("0.0.0.0"))) {
+          fallback_faddr = &faddr;
+        }
+
+        break;
+      case AF_INET6:
+        if (util::streq(faddr.hostport, StringRef::from_lit("[::]"))) {
+          fallback_faddr = &faddr;
+        }
+
+        break;
+      default:
+        assert(0);
+      }
+    } else {
+      switch (faddr.family) {
+      case AF_INET:
+        if (util::starts_with(faddr.hostport,
+                              StringRef::from_lit("0.0.0.0:"))) {
+          fallback_faddr = &faddr;
+        }
+
+        break;
+      case AF_INET6:
+        if (util::starts_with(faddr.hostport, StringRef::from_lit("[::]:"))) {
+          fallback_faddr = &faddr;
+        }
+
+        break;
+      default:
+        assert(0);
+      }
+    }
+  }
+
+  return fallback_faddr;
+}
+#endif // ENABLE_HTTP3
+
 namespace {
 size_t match_downstream_addr_group_host(
     const RouterConfig &routerconf, const StringRef &host,
@@ -744,4 +1267,16 @@ void downstream_failure(DownstreamAddr *addr, const Address *raddr) {
   }
 }
 
+#ifdef ENABLE_HTTP3
+int create_cid_prefix(uint8_t *cid_prefix, const uint8_t *server_id) {
+  auto p = std::copy_n(server_id, SHRPX_QUIC_SERVER_IDLEN, cid_prefix);
+
+  if (RAND_bytes(p, SHRPX_QUIC_CID_PREFIXLEN - SHRPX_QUIC_SERVER_IDLEN) != 1) {
+    return -1;
+  }
+
+  return 0;
+}
+#endif // ENABLE_HTTP3
+
 } // namespace shrpx
index 53f37cb..8cf40e9 100644 (file)
 #include "shrpx_live_check.h"
 #include "shrpx_connect_blocker.h"
 #include "shrpx_dns_tracker.h"
+#ifdef ENABLE_HTTP3
+#  include "shrpx_quic_connection_handler.h"
+#  include "shrpx_quic.h"
+#endif // ENABLE_HTTP3
 #include "allocator.h"
 
 using namespace nghttp2;
@@ -61,6 +65,9 @@ class ConnectBlocker;
 class MemcachedDispatcher;
 struct UpstreamAddr;
 class ConnectionHandler;
+#ifdef ENABLE_HTTP3
+class QUICListener;
+#endif // ENABLE_HTTP3
 
 #ifdef HAVE_MRUBY
 namespace mruby {
@@ -153,7 +160,7 @@ struct DownstreamAddrEntryGreater {
     if (d == 0) {
       return rhs.seq < lhs.seq;
     }
-    return d <= MAX_DOWNSTREAM_ADDR_WEIGHT;
+    return d <= 2 * MAX_DOWNSTREAM_ADDR_WEIGHT - 1;
   }
 };
 
@@ -182,7 +189,7 @@ struct WeightGroupEntryGreater {
     if (d == 0) {
       return rhs.seq < lhs.seq;
     }
-    return d <= MAX_DOWNSTREAM_ADDR_WEIGHT;
+    return d <= 2 * MAX_DOWNSTREAM_ADDR_WEIGHT - 1;
   }
 };
 
@@ -191,6 +198,7 @@ struct SharedDownstreamAddr {
       : balloc(1024, 1024),
         affinity{SessionAffinity::NONE},
         redirect_if_not_tls{false},
+        dnf{false},
         timeout{} {}
 
   SharedDownstreamAddr(const SharedDownstreamAddr &) = delete;
@@ -216,6 +224,8 @@ struct SharedDownstreamAddr {
   // true if this group requires that client connection must be TLS,
   // and the request must be redirected to https URI.
   bool redirect_if_not_tls;
+  // true if a request should not be forwarded to a backend.
+  bool dnf;
   // Timeouts for backend connection.
   struct {
     ev_tstamp read;
@@ -242,13 +252,33 @@ struct DownstreamAddrGroup {
 
 struct WorkerStat {
   size_t num_connections;
+  size_t num_close_waits;
 };
 
+#ifdef ENABLE_HTTP3
+struct QUICPacket {
+  QUICPacket(size_t upstream_addr_index, const Address &remote_addr,
+             const Address &local_addr, const uint8_t *data, size_t datalen)
+      : upstream_addr_index{upstream_addr_index},
+        remote_addr{remote_addr},
+        local_addr{local_addr},
+        data{data, data + datalen} {}
+  QUICPacket() {}
+  size_t upstream_addr_index;
+  Address remote_addr;
+  Address local_addr;
+  std::vector<uint8_t> data;
+};
+#endif // ENABLE_HTTP3
+
 enum class WorkerEventType {
   NEW_CONNECTION = 0x01,
   REOPEN_LOG = 0x02,
   GRACEFUL_SHUTDOWN = 0x03,
   REPLACE_DOWNSTREAM = 0x04,
+#ifdef ENABLE_HTTP3
+  QUIC_PKT_FORWARD = 0x05,
+#endif // ENABLE_HTTP3
 };
 
 struct WorkerEvent {
@@ -261,6 +291,9 @@ struct WorkerEvent {
   };
   std::shared_ptr<TicketKeys> ticket_keys;
   std::shared_ptr<DownstreamConfig> downstreamconf;
+#ifdef ENABLE_HTTP3
+  std::unique_ptr<QUICPacket> quic_pkt;
+#endif // ENABLE_HTTP3
 };
 
 class Worker {
@@ -268,6 +301,13 @@ public:
   Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
          SSL_CTX *tls_session_cache_memcached_ssl_ctx,
          tls::CertLookupTree *cert_tree,
+#ifdef ENABLE_HTTP3
+         SSL_CTX *quic_sv_ssl_ctx, tls::CertLookupTree *quic_cert_tree,
+         const uint8_t *cid_prefix, size_t cid_prefixlen,
+#  ifdef HAVE_LIBBPF
+         size_t index,
+#  endif // HAVE_LIBBPF
+#endif   // ENABLE_HTTP3
          const std::shared_ptr<TicketKeys> &ticket_keys,
          ConnectionHandler *conn_handler,
          std::shared_ptr<DownstreamConfig> downstreamconf);
@@ -275,9 +315,12 @@ public:
   void run_async();
   void wait();
   void process_events();
-  void send(const WorkerEvent &event);
+  void send(WorkerEvent event);
 
   tls::CertLookupTree *get_cert_lookup_tree() const;
+#ifdef ENABLE_HTTP3
+  tls::CertLookupTree *get_quic_cert_lookup_tree() const;
+#endif // ENABLE_HTTP3
 
   // These 2 functions make a lock m_ to get/set ticket keys
   // atomically.
@@ -288,6 +331,9 @@ public:
   struct ev_loop *get_loop() const;
   SSL_CTX *get_sv_ssl_ctx() const;
   SSL_CTX *get_cl_ssl_ctx() const;
+#ifdef ENABLE_HTTP3
+  SSL_CTX *get_quic_sv_ssl_ctx() const;
+#endif // ENABLE_HTTP3
 
   void set_graceful_shutdown(bool f);
   bool get_graceful_shutdown() const;
@@ -317,12 +363,37 @@ public:
 
   ConnectionHandler *get_connection_handler() const;
 
+#ifdef ENABLE_HTTP3
+  QUICConnectionHandler *get_quic_connection_handler();
+
+  int setup_quic_server_socket();
+
+  const uint8_t *get_cid_prefix() const;
+
+#  ifdef HAVE_LIBBPF
+  bool should_attach_bpf() const;
+
+  bool should_update_bpf_map() const;
+
+  uint32_t compute_sk_index() const;
+#  endif // HAVE_LIBBPF
+
+  int create_quic_server_socket(UpstreamAddr &addr);
+
+  // Returns a pointer to UpstreamAddr which matches |local_addr|.
+  const UpstreamAddr *find_quic_upstream_addr(const Address &local_addr);
+#endif // ENABLE_HTTP3
+
   DNSTracker *get_dns_tracker();
 
 private:
 #ifndef NOTHREADS
   std::future<void> fut_;
 #endif // NOTHREADS
+#if defined(ENABLE_HTTP3) && defined(HAVE_LIBBPF)
+  // Unique index of this worker.
+  size_t index_;
+#endif // ENABLE_HTTP3 && HAVE_LIBBPF
   std::mutex m_;
   std::deque<WorkerEvent> q_;
   std::mt19937 randgen_;
@@ -333,6 +404,12 @@ private:
   WorkerStat worker_stat_;
   DNSTracker dns_tracker_;
 
+#ifdef ENABLE_HTTP3
+  std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN> cid_prefix_;
+  std::vector<UpstreamAddr> quic_upstream_addrs_;
+  std::vector<std::unique_ptr<QUICListener>> quic_listeners_;
+#endif // ENABLE_HTTP3
+
   std::shared_ptr<DownstreamConfig> downstreamconf_;
   std::unique_ptr<MemcachedDispatcher> session_cache_memcached_dispatcher_;
 #ifdef HAVE_MRUBY
@@ -346,6 +423,12 @@ private:
   SSL_CTX *cl_ssl_ctx_;
   tls::CertLookupTree *cert_tree_;
   ConnectionHandler *conn_handler_;
+#ifdef ENABLE_HTTP3
+  SSL_CTX *quic_sv_ssl_ctx_;
+  tls::CertLookupTree *quic_cert_tree_;
+
+  QUICConnectionHandler quic_conn_handler_;
+#endif // ENABLE_HTTP3
 
 #ifndef HAVE_ATOMIC_STD_SHARED_PTR
   std::mutex ticket_keys_m_;
@@ -376,6 +459,13 @@ size_t match_downstream_addr_group(
 // nullptr.  This function may schedule live check.
 void downstream_failure(DownstreamAddr *addr, const Address *raddr);
 
+#ifdef ENABLE_HTTP3
+// Creates unpredictable SHRPX_QUIC_CID_PREFIXLEN bytes sequence which
+// is used as a prefix of QUIC Connection ID.  This function returns
+// -1 on failure.  |server_id| must be 2 bytes long.
+int create_cid_prefix(uint8_t *cid_prefix, const uint8_t *server_id);
+#endif // ENABLE_HTTP3
+
 } // namespace shrpx
 
 #endif // SHRPX_WORKER_H
index dc95701..517df30 100644 (file)
@@ -123,7 +123,9 @@ void graceful_shutdown(ConnectionHandler *conn_handler) {
 
   auto single_worker = conn_handler->get_single_worker();
   if (single_worker) {
-    if (single_worker->get_worker_stat()->num_connections == 0) {
+    auto worker_stat = single_worker->get_worker_stat();
+    if (worker_stat->num_connections == 0 &&
+        worker_stat->num_close_waits == 0) {
       ev_break(conn_handler->get_loop());
     }
 
@@ -178,6 +180,20 @@ void ipc_readcb(struct ev_loop *loop, ev_io *w, int revents) {
 }
 } // namespace
 
+#ifdef ENABLE_HTTP3
+namespace {
+void quic_ipc_readcb(struct ev_loop *loop, ev_io *w, int revents) {
+  auto conn_handler = static_cast<ConnectionHandler *>(w->data);
+
+  if (conn_handler->quic_ipc_read() != 0) {
+    LOG(ERROR) << "Failed to read data from QUIC IPC channel";
+
+    return;
+  }
+}
+} // namespace
+#endif // ENABLE_HTTP3
+
 namespace {
 int generate_ticket_key(TicketKey &ticket_key) {
   ticket_key.cipher = get_config()->tls.ticket.cipher;
@@ -411,13 +427,6 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
 
   auto gen = util::make_mt19937();
 
-  auto conn_handler = std::make_unique<ConnectionHandler>(loop, gen);
-
-  for (auto &addr : config->conn.listener.addrs) {
-    conn_handler->add_acceptor(
-        std::make_unique<AcceptHandler>(&addr, conn_handler.get()));
-  }
-
 #ifdef HAVE_NEVERBLEED
   std::array<char, NEVERBLEED_ERRBUF_SIZE> nb_errbuf;
   auto nb = std::make_unique<neverbleed_t>();
@@ -428,8 +437,6 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
 
   LOG(NOTICE) << "neverbleed process [" << nb->daemon_pid << "] spawned";
 
-  conn_handler->set_neverbleed(nb.get());
-
   ev_child nb_childev;
 
   ev_child_init(&nb_childev, nb_child_cb, nb->daemon_pid, 0);
@@ -437,6 +444,23 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
   ev_child_start(loop, &nb_childev);
 #endif // HAVE_NEVERBLEED
 
+  auto conn_handler = std::make_unique<ConnectionHandler>(loop, gen);
+
+#ifdef HAVE_NEVERBLEED
+  conn_handler->set_neverbleed(nb.get());
+#endif // HAVE_NEVERBLEED
+
+#ifdef ENABLE_HTTP3
+  conn_handler->set_quic_ipc_fd(wpconf->quic_ipc_fd);
+  conn_handler->set_quic_lingering_worker_processes(
+      wpconf->quic_lingering_worker_processes);
+#endif // ENABLE_HTTP3
+
+  for (auto &addr : config->conn.listener.addrs) {
+    conn_handler->add_acceptor(
+        std::make_unique<AcceptHandler>(&addr, conn_handler.get()));
+  }
+
   MemchunkPool mcpool;
 
   ev_timer renew_ticket_key_timer;
@@ -494,6 +518,57 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
     }
   }
 
+#ifdef ENABLE_HTTP3
+  auto &quicconf = config->quic;
+
+  std::shared_ptr<QUICKeyingMaterials> qkms;
+
+  if (!quicconf.upstream.secret_file.empty()) {
+    qkms = read_quic_secret_file(quicconf.upstream.secret_file);
+    if (!qkms) {
+      LOG(WARN) << "Use QUIC keying materials generated internally";
+    }
+  }
+
+  if (!qkms) {
+    qkms = std::make_shared<QUICKeyingMaterials>();
+    qkms->keying_materials.resize(1);
+
+    auto &qkm = qkms->keying_materials.front();
+
+    if (RAND_bytes(qkm.reserved.data(), qkm.reserved.size()) != 1) {
+      LOG(ERROR) << "Failed to generate QUIC secret reserved data";
+      return -1;
+    }
+
+    if (RAND_bytes(qkm.secret.data(), qkm.secret.size()) != 1) {
+      LOG(ERROR) << "Failed to generate QUIC secret";
+      return -1;
+    }
+
+    if (RAND_bytes(qkm.salt.data(), qkm.salt.size()) != 1) {
+      LOG(ERROR) << "Failed to generate QUIC salt";
+      return -1;
+    }
+  }
+
+  for (auto &qkm : qkms->keying_materials) {
+    if (generate_quic_connection_id_encryption_key(
+            qkm.cid_encryption_key.data(), qkm.cid_encryption_key.size(),
+            qkm.secret.data(), qkm.secret.size(), qkm.salt.data(),
+            qkm.salt.size()) != 0) {
+      LOG(ERROR) << "Failed to generate QUIC Connection ID encryption key";
+      return -1;
+    }
+  }
+
+  conn_handler->set_quic_keying_materials(std::move(qkms));
+
+  conn_handler->set_cid_prefixes(wpconf->cid_prefixes);
+  conn_handler->set_quic_lingering_worker_processes(
+      wpconf->quic_lingering_worker_processes);
+#endif // ENABLE_HTTP3
+
   if (config->single_thread) {
     rv = conn_handler->create_single_worker();
     if (rv != 0) {
@@ -528,6 +603,10 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
 #endif // !NOTHREADS
   }
 
+#if defined(ENABLE_HTTP3) && defined(HAVE_LIBBPF)
+  conn_handler->unload_bpf_objects();
+#endif // defined(ENABLE_HTTP3) && defined(HAVE_LIBBPF)
+
   drop_privileges(
 #ifdef HAVE_NEVERBLEED
       nb.get()
@@ -539,6 +618,13 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
   ipcev.data = conn_handler.get();
   ev_io_start(loop, &ipcev);
 
+#ifdef ENABLE_HTTP3
+  ev_io quic_ipcev;
+  ev_io_init(&quic_ipcev, quic_ipc_readcb, wpconf->quic_ipc_fd, EV_READ);
+  quic_ipcev.data = conn_handler.get();
+  ev_io_start(loop, &quic_ipcev);
+#endif // ENABLE_HTTP3
+
   if (tls::upstream_tls_enabled(config->conn) && !config->tls.ocsp.disabled) {
     if (config->tls.ocsp.startup) {
       conn_handler->set_enable_acceptor_on_ocsp_completion(true);
index 01e3e67..51597a3 100644 (file)
 
 #include "shrpx.h"
 
+#include <vector>
+#include <array>
+
+#include "shrpx_connection_handler.h"
+#ifdef ENABLE_HTTP3
+#  include "shrpx_quic.h"
+#endif // ENABLE_HTTP3
+
 namespace shrpx {
 
 class ConnectionHandler;
 
 struct WorkerProcessConfig {
-  // IPC socket to read event from master process
+  // IPC socket to read event from main process
   int ipc_fd;
   // IPv4 or UNIX domain socket, or -1 if not used
   int server_fd;
   // IPv6 socket, or -1 if not used
   int server_fd6;
+#ifdef ENABLE_HTTP3
+  // CID prefixes for the new worker process.
+  std::vector<std::array<uint8_t, SHRPX_QUIC_CID_PREFIXLEN>> cid_prefixes;
+  // IPC socket to read forwarded QUIC UDP datagram from the current
+  // worker process.
+  int quic_ipc_fd;
+  // Lingering worker processes which were created before this worker
+  // process to forward QUIC UDP datagram during reload.
+  std::vector<QUICLingeringWorkerProcess> quic_lingering_worker_processes;
+#endif // ENABLE_HTTP3
 };
 
 int worker_process_event_loop(WorkerProcessConfig *wpconf);
index 9574b7c..87f326a 100644 (file)
 
 #  include <openssl/opensslv.h>
 
-#  if defined(LIBRESSL_VERSION_NUMBER)
+#  ifdef LIBRESSL_VERSION_NUMBER
 #    define OPENSSL_1_1_API 0
 #    define OPENSSL_1_1_1_API 0
+#    define OPENSSL_3_0_0_API 0
 #    define LIBRESSL_IN_USE 1
 #    define LIBRESSL_LEGACY_API (LIBRESSL_VERSION_NUMBER < 0x20700000L)
 #    define LIBRESSL_2_7_API (LIBRESSL_VERSION_NUMBER >= 0x20700000L)
-#  else // !defined(LIBRESSL_VERSION_NUMBER)
+#  else // !LIBRESSL_VERSION_NUMBER
 #    define OPENSSL_1_1_API (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
 #    define OPENSSL_1_1_1_API (OPENSSL_VERSION_NUMBER >= 0x10101000L)
+#    define OPENSSL_3_0_0_API (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 #    define LIBRESSL_IN_USE 0
 #    define LIBRESSL_LEGACY_API 0
 #    define LIBRESSL_2_7_API 0
-#  endif // !defined(LIBRESSL_VERSION_NUMBER)
+#  endif // !LIBRESSL_VERSION_NUMBER
 
 #endif // OPENSSL_COMPAT_H
index b2f850d..530a1d1 100644 (file)
@@ -45,7 +45,7 @@ template <typename... T>
 constexpr std::array<
     typename std::decay<typename std::common_type<T...>::type>::type,
     sizeof...(T)>
-make_array(T &&... t) {
+make_array(T &&...t) {
   return std::array<
       typename std::decay<typename std::common_type<T...>::type>::type,
       sizeof...(T)>{{std::forward<T>(t)...}};
@@ -62,7 +62,7 @@ template <typename T, size_t N> constexpr size_t str_size(T (&)[N]) {
 // inspired by <http://blog.korfuri.fr/post/go-defer-in-cpp/>, but our
 // template can take functions returning other than void.
 template <typename F, typename... T> struct Defer {
-  Defer(F &&f, T &&... t)
+  Defer(F &&f, T &&...t)
       : f(std::bind(std::forward<F>(f), std::forward<T>(t)...)) {}
   Defer(Defer &&o) noexcept : f(std::move(o.f)) {}
   ~Defer() { f(); }
@@ -72,7 +72,7 @@ template <typename F, typename... T> struct Defer {
   std::function<ResultType()> f;
 };
 
-template <typename F, typename... T> Defer<F, T...> defer(F &&f, T &&... t) {
+template <typename F, typename... T> Defer<F, T...> defer(F &&f, T &&...t) {
   return Defer<F, T...>(std::forward<F>(f), std::forward<T>(t)...);
 }
 
index 6920fe4..a5b0975 100644 (file)
@@ -117,7 +117,7 @@ TLSSessionInfo *get_tls_session_info(TLSSessionInfo *tls_info, SSL *ssl) {
 }
 
 /* Conditional logic w/ lookup tables to check if id is one of the
-   the black listed cipher suites for HTTP/2 described in RFC 7540.
+   the block listed cipher suites for HTTP/2 described in RFC 7540.
    https://github.com/jay/http2_blacklisted_ciphers
 */
 #define IS_CIPHER_BANNED_METHOD2(id)                                           \
@@ -132,7 +132,7 @@ TLSSessionInfo *get_tls_session_info(TLSSessionInfo *tls_info, SSL *ssl) {
             [(id & 0xFF) / 8] &                                                \
         (1 << (id % 8))))
 
-bool check_http2_cipher_black_list(SSL *ssl) {
+bool check_http2_cipher_block_list(SSL *ssl) {
   int id = SSL_CIPHER_get_id(SSL_get_current_cipher(ssl)) & 0xFFFFFF;
 
   return IS_CIPHER_BANNED_METHOD2(id);
@@ -145,7 +145,7 @@ bool check_http2_tls_version(SSL *ssl) {
 }
 
 bool check_http2_requirement(SSL *ssl) {
-  return check_http2_tls_version(ssl) && !check_http2_cipher_black_list(ssl);
+  return check_http2_tls_version(ssl) && !check_http2_cipher_block_list(ssl);
 }
 
 void libssl_init() {
index d6c10db..2a6bf45 100644 (file)
--- a/src/tls.h
+++ b/src/tls.h
@@ -57,11 +57,15 @@ constexpr char DEFAULT_CIPHER_LIST[] =
     "AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256";
 
 constexpr char DEFAULT_TLS13_CIPHER_LIST[] =
-#if OPENSSL_1_1_1_API
+#if OPENSSL_3_0_0_API
+    "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
+#elif OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
     TLS_DEFAULT_CIPHERSUITES
-#else  // !OPENSSL_1_1_1_API
+#else  // !OPENSSL_3_0_0_API && !(OPENSSL_1_1_1_API &&
+       // !defined(OPENSSL_IS_BORINGSSL))
     ""
-#endif // !OPENSSL_1_1_1_API
+#endif // !OPENSSL_3_0_0_API && !(OPENSSL_1_1_1_API &&
+       // !defined(OPENSSL_IS_BORINGSSL))
     ;
 
 constexpr auto NGHTTP2_TLS_MIN_VERSION = TLS1_VERSION;
@@ -87,14 +91,14 @@ TLSSessionInfo *get_tls_session_info(TLSSessionInfo *tls_info, SSL *ssl);
 bool check_http2_tls_version(SSL *ssl);
 
 // Returns true iff the negotiated cipher suite is in HTTP/2 cipher
-// black list.
-bool check_http2_cipher_black_list(SSL *ssl);
+// block list.
+bool check_http2_cipher_block_list(SSL *ssl);
 
 // Returns true if SSL/TLS requirement for HTTP/2 is fulfilled.
 // To fulfill the requirement, the following 2 terms must be hold:
 //
 // 1. The negotiated protocol must be TLSv1.2.
-// 2. The negotiated cipher cuite is not listed in the black list
+// 2. The negotiated cipher cuite is not listed in the block list
 //    described in RFC 7540.
 bool check_http2_requirement(SSL *ssl);
 
index 187fd3a..213989e 100644 (file)
@@ -167,24 +167,29 @@ bool in_attr_char(char c) {
 StringRef percent_encode_token(BlockAllocator &balloc,
                                const StringRef &target) {
   auto iov = make_byte_ref(balloc, target.size() * 3 + 1);
-  auto p = iov.base;
+  auto p = percent_encode_token(iov.base, target);
+
+  *p = '\0';
+
+  return StringRef{iov.base, p};
+}
+
+size_t percent_encode_tokenlen(const StringRef &target) {
+  size_t n = 0;
 
   for (auto first = std::begin(target); first != std::end(target); ++first) {
     uint8_t c = *first;
 
     if (c != '%' && in_token(c)) {
-      *p++ = c;
+      ++n;
       continue;
     }
 
-    *p++ = '%';
-    *p++ = UPPER_XDIGITS[c >> 4];
-    *p++ = UPPER_XDIGITS[(c & 0x0f)];
+    // percent-encoded character '%ff'
+    n += 3;
   }
 
-  *p = '\0';
-
-  return StringRef{iov.base, p};
+  return n;
 }
 
 uint32_t hex_to_uint(char c) {
@@ -208,19 +213,25 @@ StringRef quote_string(BlockAllocator &balloc, const StringRef &target) {
   }
 
   auto iov = make_byte_ref(balloc, target.size() + cnt + 1);
-  auto p = iov.base;
+  auto p = quote_string(iov.base, target);
+
+  *p = '\0';
+
+  return StringRef{iov.base, p};
+}
+
+size_t quote_stringlen(const StringRef &target) {
+  size_t n = 0;
 
   for (auto c : target) {
     if (c == '"') {
-      *p++ = '\\';
-      *p++ = '"';
+      n += 2;
     } else {
-      *p++ = c;
+      ++n;
     }
   }
-  *p = '\0';
 
-  return StringRef{iov.base, p};
+  return n;
 }
 
 namespace {
@@ -385,6 +396,47 @@ char *iso8601_date(char *res, int64_t ms) {
   return p;
 }
 
+char *iso8601_basic_date(char *res, int64_t ms) {
+  time_t sec = ms / 1000;
+
+  tm tms;
+  if (localtime_r(&sec, &tms) == nullptr) {
+    return res;
+  }
+
+  auto p = res;
+
+  p = cpydig(p, tms.tm_year + 1900, 4);
+  p = cpydig(p, tms.tm_mon + 1, 2);
+  p = cpydig(p, tms.tm_mday, 2);
+  *p++ = 'T';
+  p = cpydig(p, tms.tm_hour, 2);
+  p = cpydig(p, tms.tm_min, 2);
+  p = cpydig(p, tms.tm_sec, 2);
+  *p++ = '.';
+  p = cpydig(p, ms % 1000, 3);
+
+#ifdef HAVE_STRUCT_TM_TM_GMTOFF
+  auto gmtoff = tms.tm_gmtoff;
+#else  // !HAVE_STRUCT_TM_TM_GMTOFF
+  auto gmtoff = nghttp2_timegm(&tms) - sec;
+#endif // !HAVE_STRUCT_TM_TM_GMTOFF
+  if (gmtoff == 0) {
+    *p++ = 'Z';
+  } else {
+    if (gmtoff > 0) {
+      *p++ = '+';
+    } else {
+      *p++ = '-';
+      gmtoff = -gmtoff;
+    }
+    p = cpydig(p, gmtoff / 3600, 2);
+    p = cpydig(p, (gmtoff % 3600) / 60, 2);
+  }
+
+  return p;
+}
+
 #ifdef _WIN32
 namespace bt = boost::posix_time;
 // one-time definition of the locale that is used to parse UTC strings
@@ -686,18 +738,21 @@ std::string numeric_name(const struct sockaddr *sa, socklen_t salen) {
 }
 
 std::string to_numeric_addr(const Address *addr) {
-  auto family = addr->su.storage.ss_family;
+  return to_numeric_addr(&addr->su.sa, addr->len);
+}
+
+std::string to_numeric_addr(const struct sockaddr *sa, socklen_t salen) {
+  auto family = sa->sa_family;
 #ifndef _WIN32
   if (family == AF_UNIX) {
-    return addr->su.un.sun_path;
+    return reinterpret_cast<const sockaddr_un *>(sa)->sun_path;
   }
 #endif // !_WIN32
 
   std::array<char, NI_MAXHOST> host;
   std::array<char, NI_MAXSERV> serv;
-  auto rv =
-      getnameinfo(&addr->su.sa, addr->len, host.data(), host.size(),
-                  serv.data(), serv.size(), NI_NUMERICHOST | NI_NUMERICSERV);
+  auto rv = getnameinfo(sa, salen, host.data(), host.size(), serv.data(),
+                        serv.size(), NI_NUMERICHOST | NI_NUMERICSERV);
   if (rv != 0) {
     return "unknown";
   }
@@ -868,6 +923,42 @@ std::vector<StringRef> split_str(const StringRef &s, char delim) {
   return list;
 }
 
+std::vector<StringRef> split_str(const StringRef &s, char delim, size_t n) {
+  if (n == 0) {
+    return split_str(s, delim);
+  }
+
+  if (n == 1) {
+    return {s};
+  }
+
+  size_t len = 1;
+  auto last = std::end(s);
+  StringRef::const_iterator d;
+  for (auto first = std::begin(s);
+       len < n && (d = std::find(first, last, delim)) != last;
+       ++len, first = d + 1)
+    ;
+
+  auto list = std::vector<StringRef>(len);
+
+  len = 0;
+  for (auto first = std::begin(s);; ++len) {
+    if (len == n - 1) {
+      list[len] = StringRef{first, last};
+      break;
+    }
+
+    auto stop = std::find(first, last, delim);
+    list[len] = StringRef{first, stop};
+    if (stop == last) {
+      break;
+    }
+    first = stop + 1;
+  }
+  return list;
+}
+
 std::vector<std::string> parse_config_str_list(const StringRef &s, char delim) {
   auto sublist = split_str(s, delim);
   auto res = std::vector<std::string>();
@@ -945,6 +1036,56 @@ int create_nonblock_socket(int family) {
   return fd;
 }
 
+int create_nonblock_udp_socket(int family) {
+#ifdef SOCK_NONBLOCK
+  auto fd = socket(family, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+
+  if (fd == -1) {
+    return -1;
+  }
+#else  // !SOCK_NONBLOCK
+  auto fd = socket(family, SOCK_DGRAM, 0);
+
+  if (fd == -1) {
+    return -1;
+  }
+
+  make_socket_nonblocking(fd);
+  make_socket_closeonexec(fd);
+#endif // !SOCK_NONBLOCK
+
+  return fd;
+}
+
+int bind_any_addr_udp(int fd, int family) {
+  addrinfo hints{};
+  addrinfo *res, *rp;
+  int rv;
+
+  hints.ai_family = family;
+  hints.ai_socktype = SOCK_DGRAM;
+  hints.ai_flags = AI_PASSIVE;
+
+  rv = getaddrinfo(nullptr, "0", &hints, &res);
+  if (rv != 0) {
+    return -1;
+  }
+
+  for (rp = res; rp; rp = rp->ai_next) {
+    if (bind(fd, rp->ai_addr, rp->ai_addrlen) != -1) {
+      break;
+    }
+  }
+
+  freeaddrinfo(res);
+
+  if (!rp) {
+    return -1;
+  }
+
+  return 0;
+}
+
 bool check_socket_connected(int fd) {
   int error;
   socklen_t len = sizeof(error);
@@ -1184,81 +1325,14 @@ std::string dtos(double n) {
 
 StringRef make_http_hostport(BlockAllocator &balloc, const StringRef &host,
                              uint16_t port) {
-  if (port != 80 && port != 443) {
-    return make_hostport(balloc, host, port);
-  }
-
-  auto ipv6 = ipv6_numeric_addr(host.c_str());
-
-  auto iov = make_byte_ref(balloc, host.size() + (ipv6 ? 2 : 0) + 1);
-  auto p = iov.base;
-
-  if (ipv6) {
-    *p++ = '[';
-  }
-
-  p = std::copy(std::begin(host), std::end(host), p);
-
-  if (ipv6) {
-    *p++ = ']';
-  }
-
-  *p = '\0';
-
-  return StringRef{iov.base, p};
-}
-
-std::string make_hostport(const StringRef &host, uint16_t port) {
-  auto ipv6 = ipv6_numeric_addr(host.c_str());
-  auto serv = utos(port);
-
-  std::string hostport;
-  hostport.resize(host.size() + (ipv6 ? 2 : 0) + 1 + serv.size());
-
-  auto p = &hostport[0];
-
-  if (ipv6) {
-    *p++ = '[';
-  }
-
-  p = std::copy_n(host.c_str(), host.size(), p);
-
-  if (ipv6) {
-    *p++ = ']';
-  }
-
-  *p++ = ':';
-  std::copy_n(serv.c_str(), serv.size(), p);
-
-  return hostport;
+  auto iov = make_byte_ref(balloc, host.size() + 2 + 1 + 5 + 1);
+  return make_http_hostport(iov.base, host, port);
 }
 
 StringRef make_hostport(BlockAllocator &balloc, const StringRef &host,
                         uint16_t port) {
-  auto ipv6 = ipv6_numeric_addr(host.c_str());
-  auto serv = utos(port);
-
-  auto iov =
-      make_byte_ref(balloc, host.size() + (ipv6 ? 2 : 0) + 1 + serv.size());
-  auto p = iov.base;
-
-  if (ipv6) {
-    *p++ = '[';
-  }
-
-  p = std::copy(std::begin(host), std::end(host), p);
-
-  if (ipv6) {
-    *p++ = ']';
-  }
-
-  *p++ = ':';
-
-  p = std::copy(std::begin(serv), std::end(serv), p);
-
-  *p = '\0';
-
-  return StringRef{iov.base, p};
+  auto iov = make_byte_ref(balloc, host.size() + 2 + 1 + 5 + 1);
+  return make_hostport(iov.base, host, port);
 }
 
 namespace {
@@ -1509,10 +1583,7 @@ bool is_hex_string(const StringRef &s) {
 
 StringRef decode_hex(BlockAllocator &balloc, const StringRef &s) {
   auto iov = make_byte_ref(balloc, s.size() + 1);
-  auto p = iov.base;
-  for (auto it = std::begin(s); it != std::end(s); it += 2) {
-    *p++ = (hex_to_uint(*it) << 4) | hex_to_uint(*(it + 1));
-  }
+  auto p = decode_hex(iov.base, s);
   *p = '\0';
   return StringRef{iov.base, p};
 }
@@ -1578,7 +1649,7 @@ std::mt19937 make_mt19937() {
 }
 
 int daemonize(int nochdir, int noclose) {
-#if defined(__APPLE__)
+#ifdef __APPLE__
   pid_t pid;
   pid = fork();
   if (pid == -1) {
@@ -1612,10 +1683,46 @@ int daemonize(int nochdir, int noclose) {
     }
   }
   return 0;
-#else  // !defined(__APPLE__)
+#else  // !__APPLE__
   return daemon(nochdir, noclose);
-#endif // !defined(__APPLE__)
+#endif // !__APPLE__
+}
+
+#ifdef ENABLE_HTTP3
+int msghdr_get_local_addr(Address &dest, msghdr *msg, int family) {
+  switch (family) {
+  case AF_INET:
+    for (auto cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+      if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
+        auto pktinfo = reinterpret_cast<in_pktinfo *>(CMSG_DATA(cmsg));
+        dest.len = sizeof(dest.su.in);
+        auto &sa = dest.su.in;
+        sa.sin_family = AF_INET;
+        sa.sin_addr = pktinfo->ipi_addr;
+
+        return 0;
+      }
+    }
+
+    return -1;
+  case AF_INET6:
+    for (auto cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+      if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
+        auto pktinfo = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cmsg));
+        dest.len = sizeof(dest.su.in6);
+        auto &sa = dest.su.in6;
+        sa.sin6_family = AF_INET6;
+        sa.sin6_addr = pktinfo->ipi6_addr;
+        return 0;
+      }
+    }
+
+    return -1;
+  }
+
+  return -1;
 }
+#endif // ENABLE_HTTP3
 
 } // namespace util
 
index 3443fe0..4d5cef3 100644 (file)
@@ -74,6 +74,8 @@ constexpr size_t NGHTTP2_MAX_UINT64_DIGITS = str_size("18446744073709551615");
 
 namespace util {
 
+extern const char UPPER_XDIGITS[];
+
 inline bool is_alpha(const char c) {
   return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
 }
@@ -136,10 +138,52 @@ StringRef percent_decode(BlockAllocator &balloc, const StringRef &src);
 // Percent encode |target| if character is not in token or '%'.
 StringRef percent_encode_token(BlockAllocator &balloc, const StringRef &target);
 
+template <typename OutputIt>
+OutputIt percent_encode_token(OutputIt it, const StringRef &target) {
+  for (auto first = std::begin(target); first != std::end(target); ++first) {
+    uint8_t c = *first;
+
+    if (c != '%' && in_token(c)) {
+      *it++ = c;
+      continue;
+    }
+
+    *it++ = '%';
+    *it++ = UPPER_XDIGITS[c >> 4];
+    *it++ = UPPER_XDIGITS[(c & 0x0f)];
+  }
+
+  return it;
+}
+
+// Returns the number of bytes written by percent_encode_token with
+// the same |target| parameter.  The return value does not include a
+// terminal NUL byte.
+size_t percent_encode_tokenlen(const StringRef &target);
+
 // Returns quotedString version of |target|.  Currently, this function
 // just replace '"' with '\"'.
 StringRef quote_string(BlockAllocator &balloc, const StringRef &target);
 
+template <typename OutputIt>
+OutputIt quote_string(OutputIt it, const StringRef &target) {
+  for (auto c : target) {
+    if (c == '"') {
+      *it++ = '\\';
+      *it++ = '"';
+    } else {
+      *it++ = c;
+    }
+  }
+
+  return it;
+}
+
+// Returns the number of bytes written by quote_string with the same
+// |target| parameter.  The return value does not include a terminal
+// NUL byte.
+size_t quote_stringlen(const StringRef &target);
+
 std::string format_hex(const unsigned char *s, size_t len);
 
 template <size_t N> std::string format_hex(const unsigned char (&s)[N]) {
@@ -170,6 +214,15 @@ OutputIt format_hex(OutputIt it, const StringRef &s) {
 // == true.
 StringRef decode_hex(BlockAllocator &balloc, const StringRef &s);
 
+template <typename OutputIt>
+OutputIt decode_hex(OutputIt d_first, const StringRef &s) {
+  for (auto it = std::begin(s); it != std::end(s); it += 2) {
+    *d_first++ = (hex_to_uint(*it) << 4) | hex_to_uint(*(it + 1));
+  }
+
+  return d_first;
+}
+
 // Returns given time |t| from epoch in HTTP Date format (e.g., Mon,
 // 10 Oct 2016 10:25:58 GMT).
 std::string http_date(time_t t);
@@ -194,6 +247,11 @@ std::string iso8601_date(int64_t ms);
 // function returns the one beyond the last position.
 char *iso8601_date(char *res, int64_t ms);
 
+// Writes given time |t| from epoch in ISO 8601 basic format into the
+// buffer pointed by |res|.  The buffer must be at least 24 bytes
+// long.  This function returns the one beyond the last position.
+char *iso8601_basic_date(char *res, int64_t ms);
+
 time_t parse_http_date(const StringRef &s);
 
 // Parses time formatted as "MMM DD HH:MM:SS YYYY [GMT]" (e.g., Feb 3
@@ -443,8 +501,6 @@ template <typename T> std::string utos_funit(T n) {
   return dtos(static_cast<double>(n) / (1 << b)) + u;
 }
 
-extern const char UPPER_XDIGITS[];
-
 template <typename T> std::string utox(T n) {
   std::string res;
   if (n == 0) {
@@ -505,6 +561,8 @@ std::string numeric_name(const struct sockaddr *sa, socklen_t salen);
 // IPv6 address, address is enclosed by square brackets ([]).
 std::string to_numeric_addr(const Address *addr);
 
+std::string to_numeric_addr(const struct sockaddr *sa, socklen_t salen);
+
 // Sets |port| to |addr|.
 void set_port(Address &addr, uint16_t port);
 
@@ -562,6 +620,11 @@ std::vector<std::string> parse_config_str_list(const StringRef &s,
 // treated as a part of substring.
 std::vector<StringRef> split_str(const StringRef &s, char delim);
 
+// Behaves like split_str, but this variant splits at most |n| - 1
+// times and returns at most |n| sub-strings.  If |n| is zero, it
+// falls back to split_str.
+std::vector<StringRef> split_str(const StringRef &s, char delim, size_t n);
+
 // Writes given time |tp| in Common Log format (e.g.,
 // 03/Jul/2014:00:19:38 +0900) in buffer pointed by |out|.  The buffer
 // must be at least 27 bytes, including terminal NULL byte.  Expected
@@ -599,6 +662,20 @@ template <typename T> StringRef format_iso8601(char *out, const T &tp) {
   return StringRef{out, p};
 }
 
+// Writes given time |tp| in ISO 8601 basic format (e.g.,
+// 20141115T125824.741Z or 20141115T125824.741+0900) in buffer pointed
+// by |out|.  The buffer must be at least 25 bytes, including terminal
+// NULL byte.  Expected type of |tp| is std::chrono::time_point.  This
+// function returns StringRef wrapping the buffer pointed by |out|,
+// and this string is terminated by NULL.
+template <typename T> StringRef format_iso8601_basic(char *out, const T &tp) {
+  auto t = std::chrono::duration_cast<std::chrono::milliseconds>(
+      tp.time_since_epoch());
+  auto p = iso8601_basic_date(out, t.count());
+  *p = '\0';
+  return StringRef{out, p};
+}
+
 // Writes given time |tp| in HTTP Date format (e.g., Mon, 10 Oct 2016
 // 10:25:58 GMT) in buffer pointed by |out|.  The buffer must be at
 // least 30 bytes, including terminal NULL byte.  Expected type of
@@ -626,6 +703,9 @@ int make_socket_nonblocking(int fd);
 int make_socket_nodelay(int fd);
 
 int create_nonblock_socket(int family);
+int create_nonblock_udp_socket(int family);
+
+int bind_any_addr_udp(int fd, int family);
 
 bool check_socket_connected(int fd);
 
@@ -682,18 +762,71 @@ std::string format_duration(const std::chrono::microseconds &u);
 // Just like above, but this takes |t| as seconds.
 std::string format_duration(double t);
 
+// The maximum buffer size including terminal NULL to store the result
+// of make_hostport.
+constexpr size_t max_hostport = NI_MAXHOST + /* [] for IPv6 */ 2 + /* : */ 1 +
+                                /* port */ 5 + /* terminal NULL */ 1;
+
+// Just like make_http_hostport(), but doesn't treat 80 and 443
+// specially.
+StringRef make_hostport(BlockAllocator &balloc, const StringRef &host,
+                        uint16_t port);
+
+template <typename OutputIt>
+StringRef make_hostport(OutputIt first, const StringRef &host, uint16_t port) {
+  auto ipv6 = ipv6_numeric_addr(host.c_str());
+  auto serv = utos(port);
+  auto p = first;
+
+  if (ipv6) {
+    *p++ = '[';
+  }
+
+  p = std::copy(std::begin(host), std::end(host), p);
+
+  if (ipv6) {
+    *p++ = ']';
+  }
+
+  *p++ = ':';
+
+  p = std::copy(std::begin(serv), std::end(serv), p);
+
+  *p = '\0';
+
+  return StringRef{first, p};
+}
+
 // Creates "host:port" string using given |host| and |port|.  If
 // |host| is numeric IPv6 address (e.g., ::1), it is enclosed by "["
 // and "]".  If |port| is 80 or 443, port part is omitted.
 StringRef make_http_hostport(BlockAllocator &balloc, const StringRef &host,
                              uint16_t port);
 
-// Just like make_http_hostport(), but doesn't treat 80 and 443
-// specially.
-std::string make_hostport(const StringRef &host, uint16_t port);
+template <typename OutputIt>
+StringRef make_http_hostport(OutputIt first, const StringRef &host,
+                             uint16_t port) {
+  if (port != 80 && port != 443) {
+    return make_hostport(first, host, port);
+  }
 
-StringRef make_hostport(BlockAllocator &balloc, const StringRef &host,
-                        uint16_t port);
+  auto ipv6 = ipv6_numeric_addr(host.c_str());
+  auto p = first;
+
+  if (ipv6) {
+    *p++ = '[';
+  }
+
+  p = std::copy(std::begin(host), std::end(host), p);
+
+  if (ipv6) {
+    *p++ = ']';
+  }
+
+  *p = '\0';
+
+  return StringRef{first, p};
+}
 
 // Dumps |src| of length |len| in the format similar to `hexdump -C`.
 void hexdump(FILE *out, const uint8_t *src, size_t len);
@@ -783,6 +916,10 @@ std::mt19937 make_mt19937();
 // daemon() using fork().
 int daemonize(int nochdir, int noclose);
 
+#ifdef ENABLE_HTTP3
+int msghdr_get_local_addr(Address &dest, msghdr *msg, int family);
+#endif // ENABLE_HTTP3
+
 } // namespace util
 
 } // namespace nghttp2
index 6ad313d..17d640d 100644 (file)
@@ -540,10 +540,13 @@ void test_util_make_http_hostport(void) {
 }
 
 void test_util_make_hostport(void) {
+  std::array<char, util::max_hostport> hostport_buf;
   CU_ASSERT("localhost:80" ==
-            util::make_hostport(StringRef::from_lit("localhost"), 80));
-  CU_ASSERT("[::1]:443" ==
-            util::make_hostport(StringRef::from_lit("::1"), 443));
+            util::make_hostport(std::begin(hostport_buf),
+                                StringRef::from_lit("localhost"), 80));
+  CU_ASSERT("[::1]:443" == util::make_hostport(std::begin(hostport_buf),
+                                               StringRef::from_lit("::1"),
+                                               443));
 
   BlockAllocator balloc(4096, 4096);
   CU_ASSERT("localhost:80" ==
@@ -652,4 +655,44 @@ void test_util_split_hostport(void) {
             util::split_hostport(StringRef::from_lit("[::1]80")));
 }
 
+void test_util_split_str(void) {
+  CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("")} ==
+            util::split_str(StringRef::from_lit(""), ','));
+  CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
+            util::split_str(StringRef::from_lit("alpha"), ','));
+  CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
+                                    StringRef::from_lit("")}) ==
+            util::split_str(StringRef::from_lit("alpha,"), ','));
+  CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
+                                    StringRef::from_lit("bravo")}) ==
+            util::split_str(StringRef::from_lit("alpha,bravo"), ','));
+  CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
+                                    StringRef::from_lit("bravo"),
+                                    StringRef::from_lit("charlie")}) ==
+            util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ','));
+  CU_ASSERT(
+      (std::vector<StringRef>{StringRef::from_lit("alpha"),
+                              StringRef::from_lit("bravo"),
+                              StringRef::from_lit("charlie")}) ==
+      util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ',', 0));
+  CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("")} ==
+            util::split_str(StringRef::from_lit(""), ',', 1));
+  CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("")} ==
+            util::split_str(StringRef::from_lit(""), ',', 2));
+  CU_ASSERT(
+      (std::vector<StringRef>{StringRef::from_lit("alpha"),
+                              StringRef::from_lit("bravo,charlie")}) ==
+      util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ',', 2));
+  CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
+            util::split_str(StringRef::from_lit("alpha"), ',', 2));
+  CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
+                                    StringRef::from_lit("")}) ==
+            util::split_str(StringRef::from_lit("alpha,"), ',', 2));
+  CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
+            util::split_str(StringRef::from_lit("alpha"), ',', 0));
+  CU_ASSERT(
+      std::vector<StringRef>{StringRef::from_lit("alpha,bravo,charlie")} ==
+      util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ',', 1));
+}
+
 } // namespace shrpx
index cc34f7d..463c74f 100644 (file)
@@ -68,6 +68,7 @@ void test_util_is_hex_string(void);
 void test_util_decode_hex(void);
 void test_util_extract_host(void);
 void test_util_split_hostport(void);
+void test_util_split_str(void);
 
 } // namespace shrpx
 
index b8521a4..be73b80 100755 (executable)
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 2011-2018 Free Software Foundation, Inc.
+# Copyright (C) 2011-2021 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -42,11 +42,13 @@ print_usage ()
 {
   cat <<END
 Usage:
-  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
-              [--expect-failure={yes|no}] [--color-tests={yes|no}]
-              [--enable-hard-errors={yes|no}] [--]
+  test-driver --test-name NAME --log-file PATH --trs-file PATH
+              [--expect-failure {yes|no}] [--color-tests {yes|no}]
+              [--enable-hard-errors {yes|no}] [--]
               TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+
 The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+See the GNU Automake documentation for information.
 END
 }
 
@@ -103,8 +105,11 @@ trap "st=130; $do_exit" 2
 trap "st=141; $do_exit" 13
 trap "st=143; $do_exit" 15
 
-# Test script is run here.
-"$@" >$log_file 2>&1
+# Test script is run here. We create the file first, then append to it,
+# to ameliorate tests themselves also writing to the log file. Our tests
+# don't, but others can (automake bug#35762).
+: >"$log_file"
+"$@" >>"$log_file" 2>&1
 estatus=$?
 
 if test $enable_hard_errors = no && test $estatus -eq 99; then
@@ -126,7 +131,7 @@ esac
 # know whether the test passed or failed simply by looking at the '.log'
 # file, without the need of also peaking into the corresponding '.trs'
 # file (automake bug#11814).
-echo "$res $test_name (exit status: $estatus)" >>$log_file
+echo "$res $test_name (exit status: $estatus)" >>"$log_file"
 
 # Report outcome to console.
 echo "${col}${res}${std}: $test_name"
index 7d9f97f..5dfb4de 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -268,8 +268,6 @@ am__define_uniq_tagged_files = \
   unique=`for i in $$list; do \
     if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
   done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
 am__tty_colors_dummy = \
   mgn= red= grn= lgn= blu= brg= std=; \
   am__color_tests=no
@@ -452,6 +450,7 @@ am__set_TESTS_bases = \
   bases='$(TEST_LOGS)'; \
   bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
   bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
 RECHECK_LOGS = $(TEST_LOGS)
 TEST_SUITE_LOG = test-suite.log
 TEST_EXTENSIONS = @EXEEXT@ .test
@@ -516,11 +515,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -539,8 +541,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -551,9 +556,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -562,9 +570,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -602,8 +619,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -1044,7 +1062,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
          test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);               \
        fi;                                                             \
        echo "$${col}$$br$${std}";                                      \
-       echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";   \
+       echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
        echo "$${col}$$br$${std}";                                      \
        create_testsuite_report --maybe-color;                          \
        echo "$$col$$br$$std";                                          \
@@ -1106,7 +1124,6 @@ failmalloc.log: failmalloc$(EXEEXT)
 @am__EXEEXT_TRUE@      --log-file $$b.log --trs-file $$b.trs \
 @am__EXEEXT_TRUE@      $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
 @am__EXEEXT_TRUE@      "$$tst" $(AM_TESTS_FD_REDIRECT)
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
index 4bf83ca..6294cff 100644 (file)
@@ -37,7 +37,7 @@ static int init_suite1(void) { return 0; }
 
 static int clean_suite1(void) { return 0; }
 
-int main() {
+int main(void) {
   CU_pSuite pSuite = NULL;
   unsigned int num_tests_failed;
 
index 67eb4a1..dc41c7c 100644 (file)
@@ -47,7 +47,7 @@ static int init_suite1(void) { return 0; }
 
 static int clean_suite1(void) { return 0; }
 
-int main() {
+int main(void) {
   CU_pSuite pSuite = NULL;
   unsigned int num_tests_failed;
 
@@ -211,6 +211,8 @@ int main() {
       !CU_add_test(pSuite, "submit_extension", test_nghttp2_submit_extension) ||
       !CU_add_test(pSuite, "submit_altsvc", test_nghttp2_submit_altsvc) ||
       !CU_add_test(pSuite, "submit_origin", test_nghttp2_submit_origin) ||
+      !CU_add_test(pSuite, "submit_rst_stream",
+                   test_nghttp2_submit_rst_stream) ||
       !CU_add_test(pSuite, "session_open_stream",
                    test_nghttp2_session_open_stream) ||
       !CU_add_test(pSuite, "session_open_stream_with_idle_stream_dep",
index c5e9de3..9a87eff 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * nghttp2 - HTTP/2 C Library
  *
- * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ * Copyright (c) 2017 ngtcp2 contributors
+ * Copyright (c) 2012 nghttp2 contributors
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
 #include "nghttp2_map.h"
 
 typedef struct strentry {
-  nghttp2_map_entry map_entry;
+  nghttp2_map_key_type key;
   const char *str;
 } strentry;
 
-static void strentry_init(strentry *entry, key_type key, const char *str) {
-  nghttp2_map_entry_init(&entry->map_entry, key);
+static void strentry_init(strentry *entry, nghttp2_map_key_type key,
+                          const char *str) {
+  entry->key = key;
   entry->str = str;
 }
 
@@ -49,23 +51,23 @@ void test_nghttp2_map(void) {
   strentry_init(&baz, 3, "baz");
   strentry_init(&shrubbery, 4, "shrubbery");
 
-  CU_ASSERT(0 == nghttp2_map_insert(&map, &foo.map_entry));
+  CU_ASSERT(0 == nghttp2_map_insert(&map, foo.key, &foo));
   CU_ASSERT(strcmp("foo", ((strentry *)nghttp2_map_find(&map, 1))->str) == 0);
   CU_ASSERT(1 == nghttp2_map_size(&map));
 
   CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
-            nghttp2_map_insert(&map, &FOO.map_entry));
+            nghttp2_map_insert(&map, FOO.key, &FOO));
 
   CU_ASSERT(1 == nghttp2_map_size(&map));
   CU_ASSERT(strcmp("foo", ((strentry *)nghttp2_map_find(&map, 1))->str) == 0);
 
-  CU_ASSERT(0 == nghttp2_map_insert(&map, &bar.map_entry));
+  CU_ASSERT(0 == nghttp2_map_insert(&map, bar.key, &bar));
   CU_ASSERT(2 == nghttp2_map_size(&map));
 
-  CU_ASSERT(0 == nghttp2_map_insert(&map, &baz.map_entry));
+  CU_ASSERT(0 == nghttp2_map_insert(&map, baz.key, &baz));
   CU_ASSERT(3 == nghttp2_map_size(&map));
 
-  CU_ASSERT(0 == nghttp2_map_insert(&map, &shrubbery.map_entry));
+  CU_ASSERT(0 == nghttp2_map_insert(&map, shrubbery.key, &shrubbery));
   CU_ASSERT(4 == nghttp2_map_size(&map));
 
   CU_ASSERT(strcmp("baz", ((strentry *)nghttp2_map_find(&map, 3))->str) == 0);
@@ -100,8 +102,8 @@ static void shuffle(int *a, int n) {
   }
 }
 
-static int eachfun(nghttp2_map_entry *entry, void *ptr) {
-  (void)entry;
+static int eachfun(void *data, void *ptr) {
+  (void)data;
   (void)ptr;
 
   return 0;
@@ -114,51 +116,56 @@ static int order[NUM_ENT];
 void test_nghttp2_map_functional(void) {
   nghttp2_map map;
   int i;
+  strentry *ent;
 
   nghttp2_map_init(&map, nghttp2_mem_default());
   for (i = 0; i < NUM_ENT; ++i) {
-    strentry_init(&arr[i], i + 1, "foo");
+    strentry_init(&arr[i], (nghttp2_map_key_type)(i + 1), "foo");
     order[i] = i + 1;
   }
   /* insertion */
   shuffle(order, NUM_ENT);
   for (i = 0; i < NUM_ENT; ++i) {
-    CU_ASSERT(0 == nghttp2_map_insert(&map, &arr[order[i] - 1].map_entry));
+    ent = &arr[order[i] - 1];
+    CU_ASSERT(0 == nghttp2_map_insert(&map, ent->key, ent));
   }
+
+  CU_ASSERT(NUM_ENT == nghttp2_map_size(&map));
+
   /* traverse */
   nghttp2_map_each(&map, eachfun, NULL);
   /* find */
   shuffle(order, NUM_ENT);
   for (i = 0; i < NUM_ENT; ++i) {
-    nghttp2_map_find(&map, order[i]);
+    CU_ASSERT(NULL != nghttp2_map_find(&map, (nghttp2_map_key_type)order[i]));
   }
   /* remove */
-  shuffle(order, NUM_ENT);
   for (i = 0; i < NUM_ENT; ++i) {
-    CU_ASSERT(0 == nghttp2_map_remove(&map, order[i]));
+    CU_ASSERT(0 == nghttp2_map_remove(&map, (nghttp2_map_key_type)order[i]));
   }
 
   /* each_free (but no op function for testing purpose) */
   for (i = 0; i < NUM_ENT; ++i) {
-    strentry_init(&arr[i], i + 1, "foo");
+    strentry_init(&arr[i], (nghttp2_map_key_type)(i + 1), "foo");
   }
   /* insert once again */
   for (i = 0; i < NUM_ENT; ++i) {
-    CU_ASSERT(0 == nghttp2_map_insert(&map, &arr[i].map_entry));
+    ent = &arr[i];
+    CU_ASSERT(0 == nghttp2_map_insert(&map, ent->key, ent));
   }
   nghttp2_map_each_free(&map, eachfun, NULL);
   nghttp2_map_free(&map);
 }
 
-static int entry_free(nghttp2_map_entry *entry, void *ptr) {
-  nghttp2_mem *mem = ptr;
+static int entry_free(void *data, void *ptr) {
+  const nghttp2_mem *mem = ptr;
 
-  mem->free(entry, NULL);
+  mem->free(data, NULL);
   return 0;
 }
 
 void test_nghttp2_map_each_free(void) {
-  nghttp2_mem *mem = nghttp2_mem_default();
+  const nghttp2_mem *mem = nghttp2_mem_default();
   strentry *foo = mem->malloc(sizeof(strentry), NULL),
            *bar = mem->malloc(sizeof(strentry), NULL),
            *baz = mem->malloc(sizeof(strentry), NULL),
@@ -171,11 +178,29 @@ void test_nghttp2_map_each_free(void) {
   strentry_init(baz, 3, "baz");
   strentry_init(shrubbery, 4, "shrubbery");
 
-  nghttp2_map_insert(&map, &foo->map_entry);
-  nghttp2_map_insert(&map, &bar->map_entry);
-  nghttp2_map_insert(&map, &baz->map_entry);
-  nghttp2_map_insert(&map, &shrubbery->map_entry);
+  nghttp2_map_insert(&map, foo->key, foo);
+  nghttp2_map_insert(&map, bar->key, bar);
+  nghttp2_map_insert(&map, baz->key, baz);
+  nghttp2_map_insert(&map, shrubbery->key, shrubbery);
+
+  nghttp2_map_each_free(&map, entry_free, (void *)mem);
+  nghttp2_map_free(&map);
+}
+
+void test_nghttp2_map_clear(void) {
+  nghttp2_mem *mem = nghttp2_mem_default();
+  nghttp2_map map;
+  strentry foo;
+
+  strentry_init(&foo, 1, "foo");
+
+  nghttp2_map_init(&map, mem);
+
+  CU_ASSERT(0 == nghttp2_map_insert(&map, foo.key, &foo));
+
+  nghttp2_map_clear(&map);
+
+  CU_ASSERT(0 == nghttp2_map_size(&map));
 
-  nghttp2_map_each_free(&map, entry_free, mem);
   nghttp2_map_free(&map);
 }
index 62ae54b..235624d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * nghttp2 - HTTP/2 C Library
  *
- * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ * Copyright (c) 2017 ngtcp2 contributors
+ * Copyright (c) 2012 nghttp2 contributors
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -32,5 +33,6 @@
 void test_nghttp2_map(void);
 void test_nghttp2_map_functional(void);
 void test_nghttp2_map_each_free(void);
+void test_nghttp2_map_clear(void);
 
 #endif /* NGHTTP2_MAP_TEST_H */
index 33ee3ad..962e3c1 100644 (file)
@@ -6398,6 +6398,107 @@ void test_nghttp2_submit_origin(void) {
   nghttp2_session_del(session);
 }
 
+void test_nghttp2_submit_rst_stream(void) {
+  nghttp2_session *session;
+  nghttp2_session_callbacks callbacks;
+  nghttp2_outbound_item *item;
+  int rv;
+  int32_t stream_id;
+
+  memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
+
+  /* Sending RST_STREAM to idle stream (local) is ignored */
+  nghttp2_session_client_new(&session, &callbacks, NULL);
+
+  rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, 1,
+                                 NGHTTP2_NO_ERROR);
+
+  CU_ASSERT(0 == rv);
+
+  item = nghttp2_outbound_queue_top(&session->ob_reg);
+
+  CU_ASSERT(NULL == item);
+
+  nghttp2_session_del(session);
+
+  /* Sending RST_STREAM to idle stream (remote) is ignored */
+  nghttp2_session_client_new(&session, &callbacks, NULL);
+
+  rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, 2,
+                                 NGHTTP2_NO_ERROR);
+
+  CU_ASSERT(0 == rv);
+
+  item = nghttp2_outbound_queue_top(&session->ob_reg);
+
+  CU_ASSERT(NULL == item);
+
+  nghttp2_session_del(session);
+
+  /* Sending RST_STREAM to non-idle stream (local) */
+  nghttp2_session_client_new(&session, &callbacks, NULL);
+
+  open_sent_stream(session, 1);
+
+  rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, 1,
+                                 NGHTTP2_NO_ERROR);
+
+  CU_ASSERT(0 == rv);
+
+  item = nghttp2_outbound_queue_top(&session->ob_reg);
+
+  CU_ASSERT(NULL != item);
+  CU_ASSERT(NGHTTP2_RST_STREAM == item->frame.hd.type);
+  CU_ASSERT(1 == item->frame.hd.stream_id);
+
+  nghttp2_session_del(session);
+
+  /* Sending RST_STREAM to non-idle stream (remote) */
+  nghttp2_session_client_new(&session, &callbacks, NULL);
+
+  open_recv_stream(session, 2);
+
+  rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, 2,
+                                 NGHTTP2_NO_ERROR);
+
+  CU_ASSERT(0 == rv);
+
+  item = nghttp2_outbound_queue_top(&session->ob_reg);
+
+  CU_ASSERT(NULL != item);
+  CU_ASSERT(NGHTTP2_RST_STREAM == item->frame.hd.type);
+  CU_ASSERT(2 == item->frame.hd.stream_id);
+
+  nghttp2_session_del(session);
+
+  /* Sending RST_STREAM to pending stream */
+  nghttp2_session_client_new(&session, &callbacks, NULL);
+
+  stream_id =
+      nghttp2_submit_request(session, NULL, reqnv, ARRLEN(reqnv), NULL, NULL);
+
+  CU_ASSERT(stream_id > 0);
+
+  item = nghttp2_outbound_queue_top(&session->ob_syn);
+
+  CU_ASSERT(NULL != item);
+  CU_ASSERT(NGHTTP2_HEADERS == item->frame.hd.type);
+  CU_ASSERT(0 == item->aux_data.headers.canceled);
+
+  rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, stream_id,
+                                 NGHTTP2_NO_ERROR);
+
+  CU_ASSERT(0 == rv);
+
+  item = nghttp2_outbound_queue_top(&session->ob_syn);
+
+  CU_ASSERT(NULL != item);
+  CU_ASSERT(NGHTTP2_HEADERS == item->frame.hd.type);
+  CU_ASSERT(1 == item->aux_data.headers.canceled);
+
+  nghttp2_session_del(session);
+}
+
 void test_nghttp2_session_open_stream(void) {
   nghttp2_session *session;
   nghttp2_session_callbacks callbacks;
index 818c808..bdedd84 100644 (file)
@@ -103,6 +103,7 @@ void test_nghttp2_submit_invalid_nv(void);
 void test_nghttp2_submit_extension(void);
 void test_nghttp2_submit_altsvc(void);
 void test_nghttp2_submit_origin(void);
+void test_nghttp2_submit_rst_stream(void);
 void test_nghttp2_session_open_stream(void);
 void test_nghttp2_session_open_stream_with_idle_stream_dep(void);
 void test_nghttp2_session_get_next_ob_item(void);
index bf3adf8..093e4fe 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -158,11 +158,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -181,8 +184,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -193,9 +199,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -204,9 +213,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -244,8 +262,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -377,7 +396,6 @@ ctags CTAGS:
 
 cscope cscopelist:
 
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
index 5925236..2d6726d 100644 (file)
@@ -23,7 +23,7 @@
 
 AM_CPPFLAGS = @DEFS@
 
-EXTRA_DIST = CMakeLists.txt
+EXTRA_DIST = CMakeLists.txt build_config.rb mruby/*
 
 if ENABLE_THIRD_PARTY
 
@@ -49,12 +49,13 @@ endif # HAVE_NEVERBLEED
 
 if HAVE_MRUBY
 
-EXTRA_DIST += build_config.rb mruby/*
-
 .PHONY: all-local clean mruby
 
 mruby:
-       MRUBY_CONFIG="${srcdir}/build_config.rb" \
+       mkdir -p "${abs_builddir}/mruby/build"
+       diff "${srcdir}/build_config.rb" "${abs_builddir}/mruby/build/build_config.rb" >& /dev/null || \
+       cp "${srcdir}/build_config.rb" "${abs_builddir}/mruby/build"
+       MRUBY_CONFIG="${abs_builddir}/mruby/build/build_config.rb" \
        BUILD_DIR="${abs_builddir}/mruby/build" \
        INSTALL_DIR="${abs_builddir}/mruby/build/install/bin" \
        CC="${CC}" CXX="$(firstword $(CXX))" LD="${LD}" \
@@ -66,8 +67,10 @@ mruby:
 all-local: mruby
 
 clean-local:
-       MRUBY_CONFIG="${srcdir}/build_config.rb" \
+       [ ! -f "${abs_builddir}/mruby/build/build_config.rb" ] || \
+       MRUBY_CONFIG="${abs_builddir}/mruby/build/build_config.rb" \
        BUILD_DIR="${abs_builddir}/mruby/build" \
+       CC="${CC}" \
        "${srcdir}/mruby/minirake" -f "${srcdir}/mruby/Rakefile" clean
 
 endif # HAVE_MRUBY
index 2d3d8dc..5e86c5d 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -113,7 +113,6 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 @ENABLE_THIRD_PARTY_TRUE@@HAVE_NEVERBLEED_TRUE@am__append_1 = libneverbleed.la
-@ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@am__append_2 = build_config.rb mruby/*
 subdir = third-party
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_asio.m4 \
@@ -227,8 +226,6 @@ am__define_uniq_tagged_files = \
   unique=`for i in $$list; do \
     if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
   done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
@@ -245,11 +242,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
 BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BPFCFLAGS = @BPFCFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
 CUNIT_CFLAGS = @CUNIT_CFLAGS@
 CUNIT_LIBS = @CUNIT_LIBS@
 CXX = @CXX@
@@ -268,8 +268,11 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
+EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
 EXTRACFLAG = @EXTRACFLAG@
+EXTRA_DEFS = @EXTRA_DEFS@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_CXX14 = @HAVE_CXX14@
@@ -280,9 +283,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 JANSSON_CFLAGS = @JANSSON_CFLAGS@
 JANSSON_LIBS = @JANSSON_LIBS@
+JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
 JEMALLOC_LIBS = @JEMALLOC_LIBS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
+LIBBPF_LIBS = @LIBBPF_LIBS@
 LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
 LIBCARES_LIBS = @LIBCARES_LIBS@
 LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -291,9 +297,18 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
 LIBEV_LIBS = @LIBEV_LIBS@
 LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
 LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
+LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
+LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
+LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
+LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
+LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
+LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
 LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
 LIBXML2_LIBS = @LIBXML2_LIBS@
 LIPO = @LIPO@
@@ -331,8 +346,9 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -412,7 +428,7 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CPPFLAGS = @DEFS@
-EXTRA_DIST = CMakeLists.txt $(am__append_2)
+EXTRA_DIST = CMakeLists.txt build_config.rb mruby/*
 @ENABLE_THIRD_PARTY_TRUE@noinst_LTLIBRARIES = liburl-parser.la \
 @ENABLE_THIRD_PARTY_TRUE@      libllhttp.la $(am__append_1)
 @ENABLE_THIRD_PARTY_TRUE@liburl_parser_la_SOURCES = \
@@ -647,7 +663,6 @@ cscopelist-am: $(am__tagged_files)
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
 distdir: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -826,7 +841,10 @@ uninstall-am:
 @ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@.PHONY: all-local clean mruby
 
 @ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@mruby:
-@ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     MRUBY_CONFIG="${srcdir}/build_config.rb" \
+@ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     mkdir -p "${abs_builddir}/mruby/build"
+@ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     diff "${srcdir}/build_config.rb" "${abs_builddir}/mruby/build/build_config.rb" >& /dev/null || \
+@ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     cp "${srcdir}/build_config.rb" "${abs_builddir}/mruby/build"
+@ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     MRUBY_CONFIG="${abs_builddir}/mruby/build/build_config.rb" \
 @ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     BUILD_DIR="${abs_builddir}/mruby/build" \
 @ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     INSTALL_DIR="${abs_builddir}/mruby/build/install/bin" \
 @ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     CC="${CC}" CXX="$(firstword $(CXX))" LD="${LD}" \
@@ -838,8 +856,10 @@ uninstall-am:
 @ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@all-local: mruby
 
 @ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@clean-local:
-@ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     MRUBY_CONFIG="${srcdir}/build_config.rb" \
+@ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     [ ! -f "${abs_builddir}/mruby/build/build_config.rb" ] || \
+@ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     MRUBY_CONFIG="${abs_builddir}/mruby/build/build_config.rb" \
 @ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     BUILD_DIR="${abs_builddir}/mruby/build" \
+@ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     CC="${CC}" \
 @ENABLE_THIRD_PARTY_TRUE@@HAVE_MRUBY_TRUE@     "${srcdir}/mruby/minirake" -f "${srcdir}/mruby/Rakefile" clean
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index 706e874..9e66958 100644 (file)
@@ -1,6 +1,6 @@
 MRuby::Build.new do |conf|
-  # TODO use same compilers configured in configure script
-  toolchain :clang
+  toolchain :clang if ENV['CC'].include? "clang"
+  toolchain :gcc if ENV['CC'].include? "gcc"
 
   # C++ project needs this.  Without this, mruby exception does not
   # properly destory C++ object allocated on stack.
index 3be7d12..2ecba18 100644 (file)
@@ -1,9 +1,13 @@
 #ifndef INCLUDE_LLHTTP_H_
 #define INCLUDE_LLHTTP_H_
 
-#define LLHTTP_VERSION_MAJOR 2
+#define LLHTTP_VERSION_MAJOR 6
 #define LLHTTP_VERSION_MINOR 0
-#define LLHTTP_VERSION_PATCH 4
+#define LLHTTP_VERSION_PATCH 2
+
+#ifndef LLHTTP_STRICT_MODE
+# define LLHTTP_STRICT_MODE 0
+#endif
 
 #ifndef INCLUDE_LLHTTP_ITSELF_H_
 #define INCLUDE_LLHTTP_ITSELF_H_
@@ -29,10 +33,11 @@ struct llhttp__internal_s {
   uint8_t http_major;
   uint8_t http_minor;
   uint8_t header_state;
-  uint16_t flags;
+  uint8_t lenient_flags;
   uint8_t upgrade;
-  uint16_t status_code;
   uint8_t finish;
+  uint16_t flags;
+  uint16_t status_code;
   void* settings;
 };
 
@@ -74,7 +79,8 @@ enum llhttp_errno {
   HPE_CB_CHUNK_COMPLETE = 20,
   HPE_PAUSED = 21,
   HPE_PAUSED_UPGRADE = 22,
-  HPE_USER = 23
+  HPE_PAUSED_H2_UPGRADE = 23,
+  HPE_USER = 24
 };
 typedef enum llhttp_errno llhttp_errno_t;
 
@@ -87,11 +93,17 @@ enum llhttp_flags {
   F_CONTENT_LENGTH = 0x20,
   F_SKIPBODY = 0x40,
   F_TRAILING = 0x80,
-  F_LENIENT = 0x100,
   F_TRANSFER_ENCODING = 0x200
 };
 typedef enum llhttp_flags llhttp_flags_t;
 
+enum llhttp_lenient_flags {
+  LENIENT_HEADERS = 0x1,
+  LENIENT_CHUNKED_LENGTH = 0x2,
+  LENIENT_KEEP_ALIVE = 0x4
+};
+typedef enum llhttp_lenient_flags llhttp_lenient_flags_t;
+
 enum llhttp_type {
   HTTP_BOTH = 0,
   HTTP_REQUEST = 1,
@@ -140,7 +152,19 @@ enum llhttp_method {
   HTTP_MKCALENDAR = 30,
   HTTP_LINK = 31,
   HTTP_UNLINK = 32,
-  HTTP_SOURCE = 33
+  HTTP_SOURCE = 33,
+  HTTP_PRI = 34,
+  HTTP_DESCRIBE = 35,
+  HTTP_ANNOUNCE = 36,
+  HTTP_SETUP = 37,
+  HTTP_PLAY = 38,
+  HTTP_PAUSE = 39,
+  HTTP_TEARDOWN = 40,
+  HTTP_GET_PARAMETER = 41,
+  HTTP_SET_PARAMETER = 42,
+  HTTP_REDIRECT = 43,
+  HTTP_RECORD = 44,
+  HTTP_FLUSH = 45
 };
 typedef enum llhttp_method llhttp_method_t;
 
@@ -168,7 +192,8 @@ typedef enum llhttp_method llhttp_method_t;
   XX(20, CB_CHUNK_COMPLETE, CB_CHUNK_COMPLETE) \
   XX(21, PAUSED, PAUSED) \
   XX(22, PAUSED_UPGRADE, PAUSED_UPGRADE) \
-  XX(23, USER, USER) \
+  XX(23, PAUSED_H2_UPGRADE, PAUSED_H2_UPGRADE) \
+  XX(24, USER, USER) \
 
 
 #define HTTP_METHOD_MAP(XX) \
@@ -208,6 +233,71 @@ typedef enum llhttp_method llhttp_method_t;
   XX(33, SOURCE, SOURCE) \
 
 
+#define RTSP_METHOD_MAP(XX) \
+  XX(1, GET, GET) \
+  XX(3, POST, POST) \
+  XX(6, OPTIONS, OPTIONS) \
+  XX(35, DESCRIBE, DESCRIBE) \
+  XX(36, ANNOUNCE, ANNOUNCE) \
+  XX(37, SETUP, SETUP) \
+  XX(38, PLAY, PLAY) \
+  XX(39, PAUSE, PAUSE) \
+  XX(40, TEARDOWN, TEARDOWN) \
+  XX(41, GET_PARAMETER, GET_PARAMETER) \
+  XX(42, SET_PARAMETER, SET_PARAMETER) \
+  XX(43, REDIRECT, REDIRECT) \
+  XX(44, RECORD, RECORD) \
+  XX(45, FLUSH, FLUSH) \
+
+
+#define HTTP_ALL_METHOD_MAP(XX) \
+  XX(0, DELETE, DELETE) \
+  XX(1, GET, GET) \
+  XX(2, HEAD, HEAD) \
+  XX(3, POST, POST) \
+  XX(4, PUT, PUT) \
+  XX(5, CONNECT, CONNECT) \
+  XX(6, OPTIONS, OPTIONS) \
+  XX(7, TRACE, TRACE) \
+  XX(8, COPY, COPY) \
+  XX(9, LOCK, LOCK) \
+  XX(10, MKCOL, MKCOL) \
+  XX(11, MOVE, MOVE) \
+  XX(12, PROPFIND, PROPFIND) \
+  XX(13, PROPPATCH, PROPPATCH) \
+  XX(14, SEARCH, SEARCH) \
+  XX(15, UNLOCK, UNLOCK) \
+  XX(16, BIND, BIND) \
+  XX(17, REBIND, REBIND) \
+  XX(18, UNBIND, UNBIND) \
+  XX(19, ACL, ACL) \
+  XX(20, REPORT, REPORT) \
+  XX(21, MKACTIVITY, MKACTIVITY) \
+  XX(22, CHECKOUT, CHECKOUT) \
+  XX(23, MERGE, MERGE) \
+  XX(24, MSEARCH, M-SEARCH) \
+  XX(25, NOTIFY, NOTIFY) \
+  XX(26, SUBSCRIBE, SUBSCRIBE) \
+  XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
+  XX(28, PATCH, PATCH) \
+  XX(29, PURGE, PURGE) \
+  XX(30, MKCALENDAR, MKCALENDAR) \
+  XX(31, LINK, LINK) \
+  XX(32, UNLINK, UNLINK) \
+  XX(33, SOURCE, SOURCE) \
+  XX(34, PRI, PRI) \
+  XX(35, DESCRIBE, DESCRIBE) \
+  XX(36, ANNOUNCE, ANNOUNCE) \
+  XX(37, SETUP, SETUP) \
+  XX(38, PLAY, PLAY) \
+  XX(39, PAUSE, PAUSE) \
+  XX(40, TEARDOWN, TEARDOWN) \
+  XX(41, GET_PARAMETER, GET_PARAMETER) \
+  XX(42, SET_PARAMETER, SET_PARAMETER) \
+  XX(43, REDIRECT, REDIRECT) \
+  XX(44, RECORD, RECORD) \
+  XX(45, FLUSH, FLUSH) \
+
 
 #ifdef __cplusplus
 }  /* extern "C" */
@@ -221,6 +311,12 @@ extern "C" {
 #endif
 #include <stddef.h>
 
+#if defined(__wasm__)
+#define LLHTTP_EXPORT __attribute__((visibility("default")))
+#else
+#define LLHTTP_EXPORT
+#endif
+
 typedef llhttp__internal_t llhttp_t;
 typedef struct llhttp_settings_s llhttp_settings_t;
 
@@ -231,6 +327,7 @@ struct llhttp_settings_s {
   /* Possible return values 0, -1, `HPE_PAUSED` */
   llhttp_cb      on_message_begin;
 
+  /* Possible return values 0, -1, HPE_USER */
   llhttp_data_cb on_url;
   llhttp_data_cb on_status;
   llhttp_data_cb on_header_field;
@@ -247,6 +344,7 @@ struct llhttp_settings_s {
    */
   llhttp_cb      on_headers_complete;
 
+  /* Possible return values 0, -1, HPE_USER */
   llhttp_data_cb on_body;
 
   /* Possible return values 0, -1, `HPE_PAUSED` */
@@ -258,13 +356,60 @@ struct llhttp_settings_s {
    */
   llhttp_cb      on_chunk_header;
   llhttp_cb      on_chunk_complete;
+
+  /* Information-only callbacks, return value is ignored */
+  llhttp_cb      on_url_complete;
+  llhttp_cb      on_status_complete;
+  llhttp_cb      on_header_field_complete;
+  llhttp_cb      on_header_value_complete;
 };
 
-/* Initialize the parser with specific type and user settings */
+/* Initialize the parser with specific type and user settings.
+ *
+ * NOTE: lifetime of `settings` has to be at least the same as the lifetime of
+ * the `parser` here. In practice, `settings` has to be either a static
+ * variable or be allocated with `malloc`, `new`, etc.
+ */
+LLHTTP_EXPORT
 void llhttp_init(llhttp_t* parser, llhttp_type_t type,
                  const llhttp_settings_t* settings);
 
+#if defined(__wasm__)
+
+LLHTTP_EXPORT
+llhttp_t* llhttp_alloc(llhttp_type_t type);
+
+LLHTTP_EXPORT
+void llhttp_free(llhttp_t* parser);
+
+LLHTTP_EXPORT
+uint8_t llhttp_get_type(llhttp_t* parser);
+
+LLHTTP_EXPORT
+uint8_t llhttp_get_http_major(llhttp_t* parser);
+
+LLHTTP_EXPORT
+uint8_t llhttp_get_http_minor(llhttp_t* parser);
+
+LLHTTP_EXPORT
+uint8_t llhttp_get_method(llhttp_t* parser);
+
+LLHTTP_EXPORT
+int llhttp_get_status_code(llhttp_t* parser);
+
+LLHTTP_EXPORT
+uint8_t llhttp_get_upgrade(llhttp_t* parser);
+
+#endif  // defined(__wasm__)
+
+/* Reset an already initialized parser back to the start state, preserving the
+ * existing parser type, callback settings, user data, and lenient flags.
+ */
+LLHTTP_EXPORT
+void llhttp_reset(llhttp_t* parser);
+
 /* Initialize the settings object */
+LLHTTP_EXPORT
 void llhttp_settings_init(llhttp_settings_t* settings);
 
 /* Parse full or partial request/response, invoking user callbacks along the
@@ -283,6 +428,7 @@ void llhttp_settings_init(llhttp_settings_t* settings);
  * to return the same error upon each successive call up until `llhttp_init()`
  * is called.
  */
+LLHTTP_EXPORT
 llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
 
 /* This method should be called when the other side has no further bytes to
@@ -293,16 +439,19 @@ llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
  * connection. This method will invoke `on_message_complete()` callback if the
  * request was terminated safely. Otherwise a error code would be returned.
  */
+LLHTTP_EXPORT
 llhttp_errno_t llhttp_finish(llhttp_t* parser);
 
 /* Returns `1` if the incoming message is parsed until the last byte, and has
  * to be completed by calling `llhttp_finish()` on EOF
  */
+LLHTTP_EXPORT
 int llhttp_message_needs_eof(const llhttp_t* parser);
 
 /* Returns `1` if there might be any other messages following the last that was
  * successfully parsed.
  */
+LLHTTP_EXPORT
 int llhttp_should_keep_alive(const llhttp_t* parser);
 
 /* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set
@@ -311,6 +460,7 @@ int llhttp_should_keep_alive(const llhttp_t* parser);
  * Important: do not call this from user callbacks! User callbacks must return
  * `HPE_PAUSED` if pausing is required.
  */
+LLHTTP_EXPORT
 void llhttp_pause(llhttp_t* parser);
 
 /* Might be called to resume the execution after the pause in user's callback.
@@ -318,6 +468,7 @@ void llhttp_pause(llhttp_t* parser);
  *
  * Call this only if `llhttp_execute()` returns `HPE_PAUSED`.
  */
+LLHTTP_EXPORT
 void llhttp_resume(llhttp_t* parser);
 
 /* Might be called to resume the execution after the pause in user's callback.
@@ -325,9 +476,11 @@ void llhttp_resume(llhttp_t* parser);
  *
  * Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE`
  */
+LLHTTP_EXPORT
 void llhttp_resume_after_upgrade(llhttp_t* parser);
 
 /* Returns the latest return error */
+LLHTTP_EXPORT
 llhttp_errno_t llhttp_get_errno(const llhttp_t* parser);
 
 /* Returns the verbal explanation of the latest returned error.
@@ -335,6 +488,7 @@ llhttp_errno_t llhttp_get_errno(const llhttp_t* parser);
  * Note: User callback should set error reason when returning the error. See
  * `llhttp_set_error_reason()` for details.
  */
+LLHTTP_EXPORT
 const char* llhttp_get_error_reason(const llhttp_t* parser);
 
 /* Assign verbal description to the returned error. Must be called in user
@@ -342,6 +496,7 @@ const char* llhttp_get_error_reason(const llhttp_t* parser);
  *
  * Note: `HPE_USER` error code might be useful in user callbacks.
  */
+LLHTTP_EXPORT
 void llhttp_set_error_reason(llhttp_t* parser, const char* reason);
 
 /* Returns the pointer to the last parsed byte before the returned error. The
@@ -349,12 +504,15 @@ void llhttp_set_error_reason(llhttp_t* parser, const char* reason);
  *
  * Note: this method might be useful for counting the number of parsed bytes.
  */
+LLHTTP_EXPORT
 const char* llhttp_get_error_pos(const llhttp_t* parser);
 
 /* Returns textual name of error code */
+LLHTTP_EXPORT
 const char* llhttp_errno_name(llhttp_errno_t err);
 
 /* Returns textual name of HTTP method */
+LLHTTP_EXPORT
 const char* llhttp_method_name(llhttp_method_t method);
 
 
@@ -367,7 +525,36 @@ const char* llhttp_method_name(llhttp_method_t method);
  *
  * **(USE AT YOUR OWN RISK)**
  */
-void llhttp_set_lenient(llhttp_t* parser, int enabled);
+LLHTTP_EXPORT
+void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
+
+
+/* Enables/disables lenient handling of conflicting `Transfer-Encoding` and
+ * `Content-Length` headers (disabled by default).
+ *
+ * Normally `llhttp` would error when `Transfer-Encoding` is present in
+ * conjunction with `Content-Length`. This error is important to prevent HTTP
+ * request smuggling, but may be less desirable for small number of cases
+ * involving legacy servers.
+ *
+ * **(USE AT YOUR OWN RISK)**
+ */
+LLHTTP_EXPORT
+void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
+
+
+/* Enables/disables lenient handling of `Connection: close` and HTTP/1.0
+ * requests responses.
+ *
+ * Normally `llhttp` would error on (in strict mode) or discard (in loose mode)
+ * the HTTP request/response after the request/response with `Connection: close`
+ * and `Content-Length`. This is important to prevent cache poisoning attacks,
+ * but might interact badly with outdated and insecure clients. With this flag
+ * the extra request/response will be parsed normally.
+ *
+ * **(USE AT YOUR OWN RISK)**
+ */
+void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled);
 
 #ifdef __cplusplus
 }  /* extern "C" */
index 6f72465..36f42fd 100644 (file)
@@ -4,15 +4,30 @@
 
 #include "llhttp.h"
 
-#define CALLBACK_MAYBE(PARSER, NAME, ...)                                     \
+#define CALLBACK_MAYBE(PARSER, NAME)                                          \
   do {                                                                        \
-    llhttp_settings_t* settings;                                              \
-    settings = (llhttp_settings_t*) (PARSER)->settings;                       \
+    const llhttp_settings_t* settings;                                        \
+    settings = (const llhttp_settings_t*) (PARSER)->settings;                 \
     if (settings == NULL || settings->NAME == NULL) {                         \
       err = 0;                                                                \
       break;                                                                  \
     }                                                                         \
-    err = settings->NAME(__VA_ARGS__);                                        \
+    err = settings->NAME((PARSER));                                           \
+  } while (0)
+
+#define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN)                         \
+  do {                                                                        \
+    const llhttp_settings_t* settings;                                        \
+    settings = (const llhttp_settings_t*) (PARSER)->settings;                 \
+    if (settings == NULL || settings->NAME == NULL) {                         \
+      err = 0;                                                                \
+      break;                                                                  \
+    }                                                                         \
+    err = settings->NAME((PARSER), (START), (LEN));                           \
+    if (err == -1) {                                                          \
+      err = HPE_USER;                                                         \
+      llhttp_set_error_reason((PARSER), "Span callback error in " #NAME);     \
+    }                                                                         \
   } while (0)
 
 void llhttp_init(llhttp_t* parser, llhttp_type_t type,
@@ -24,6 +39,85 @@ void llhttp_init(llhttp_t* parser, llhttp_type_t type,
 }
 
 
+#if defined(__wasm__)
+
+extern int wasm_on_message_begin(llhttp_t * p);
+extern int wasm_on_url(llhttp_t* p, const char* at, size_t length);
+extern int wasm_on_status(llhttp_t* p, const char* at, size_t length);
+extern int wasm_on_header_field(llhttp_t* p, const char* at, size_t length);
+extern int wasm_on_header_value(llhttp_t* p, const char* at, size_t length);
+extern int wasm_on_headers_complete(llhttp_t * p);
+extern int wasm_on_body(llhttp_t* p, const char* at, size_t length);
+extern int wasm_on_message_complete(llhttp_t * p);
+
+const llhttp_settings_t wasm_settings = {
+  wasm_on_message_begin,
+  wasm_on_url,
+  wasm_on_status,
+  wasm_on_header_field,
+  wasm_on_header_value,
+  wasm_on_headers_complete,
+  wasm_on_body,
+  wasm_on_message_complete,
+  NULL,
+  NULL,
+};
+
+
+llhttp_t* llhttp_alloc(llhttp_type_t type) {
+  llhttp_t* parser = malloc(sizeof(llhttp_t));
+  llhttp_init(parser, type, &wasm_settings);
+  return parser;
+}
+
+void llhttp_free(llhttp_t* parser) {
+  free(parser);
+}
+
+/* Some getters required to get stuff from the parser */
+
+uint8_t llhttp_get_type(llhttp_t* parser) {
+  return parser->type;
+}
+
+uint8_t llhttp_get_http_major(llhttp_t* parser) {
+  return parser->http_major;
+}
+
+uint8_t llhttp_get_http_minor(llhttp_t* parser) {
+  return parser->http_minor;
+}
+
+uint8_t llhttp_get_method(llhttp_t* parser) {
+  return parser->method;
+}
+
+int llhttp_get_status_code(llhttp_t* parser) {
+  return parser->status_code;
+}
+
+uint8_t llhttp_get_upgrade(llhttp_t* parser) {
+  return parser->upgrade;
+}
+
+#endif  // defined(__wasm__)
+
+
+void llhttp_reset(llhttp_t* parser) {
+  llhttp_type_t type = parser->type;
+  const llhttp_settings_t* settings = parser->settings;
+  void* data = parser->data;
+  uint8_t lenient_flags = parser->lenient_flags;
+
+  llhttp__internal_init(parser);
+
+  parser->type = type;
+  parser->settings = (void*) settings;
+  parser->data = data;
+  parser->lenient_flags = lenient_flags;
+}
+
+
 llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) {
   return llhttp__internal_execute(parser, data, data + len);
 }
@@ -44,7 +138,7 @@ llhttp_errno_t llhttp_finish(llhttp_t* parser) {
 
   switch (parser->finish) {
     case HTTP_FINISH_SAFE_WITH_CB:
-      CALLBACK_MAYBE(parser, on_message_complete, parser);
+      CALLBACK_MAYBE(parser, on_message_complete);
       if (err != HPE_OK) return err;
 
     /* FALLTHROUGH */
@@ -120,91 +214,136 @@ const char* llhttp_errno_name(llhttp_errno_t err) {
 const char* llhttp_method_name(llhttp_method_t method) {
 #define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
   switch (method) {
-    HTTP_METHOD_MAP(HTTP_METHOD_GEN)
+    HTTP_ALL_METHOD_MAP(HTTP_METHOD_GEN)
     default: abort();
   }
 #undef HTTP_METHOD_GEN
 }
 
 
-void llhttp_set_lenient(llhttp_t* parser, int enabled) {
+void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
   if (enabled) {
-    parser->flags |= F_LENIENT;
+    parser->lenient_flags |= LENIENT_HEADERS;
   } else {
-    parser->flags &= ~F_LENIENT;
+    parser->lenient_flags &= ~LENIENT_HEADERS;
   }
 }
 
 
+void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
+  if (enabled) {
+    parser->lenient_flags |= LENIENT_CHUNKED_LENGTH;
+  } else {
+    parser->lenient_flags &= ~LENIENT_CHUNKED_LENGTH;
+  }
+}
+
+
+void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
+  if (enabled) {
+    parser->lenient_flags |= LENIENT_KEEP_ALIVE;
+  } else {
+    parser->lenient_flags &= ~LENIENT_KEEP_ALIVE;
+  }
+}
+
 /* Callbacks */
 
 
 int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
   int err;
-  CALLBACK_MAYBE(s, on_message_begin, s);
+  CALLBACK_MAYBE(s, on_message_begin);
   return err;
 }
 
 
 int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
   int err;
-  CALLBACK_MAYBE(s, on_url, s, p, endp - p);
+  SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p);
+  return err;
+}
+
+
+int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
+  int err;
+  CALLBACK_MAYBE(s, on_url_complete);
   return err;
 }
 
 
 int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
   int err;
-  CALLBACK_MAYBE(s, on_status, s, p, endp - p);
+  SPAN_CALLBACK_MAYBE(s, on_status, p, endp - p);
+  return err;
+}
+
+
+int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) {
+  int err;
+  CALLBACK_MAYBE(s, on_status_complete);
   return err;
 }
 
 
 int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
   int err;
-  CALLBACK_MAYBE(s, on_header_field, s, p, endp - p);
+  SPAN_CALLBACK_MAYBE(s, on_header_field, p, endp - p);
+  return err;
+}
+
+
+int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) {
+  int err;
+  CALLBACK_MAYBE(s, on_header_field_complete);
   return err;
 }
 
 
 int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
   int err;
-  CALLBACK_MAYBE(s, on_header_value, s, p, endp - p);
+  SPAN_CALLBACK_MAYBE(s, on_header_value, p, endp - p);
+  return err;
+}
+
+
+int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) {
+  int err;
+  CALLBACK_MAYBE(s, on_header_value_complete);
   return err;
 }
 
 
 int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
   int err;
-  CALLBACK_MAYBE(s, on_headers_complete, s);
+  CALLBACK_MAYBE(s, on_headers_complete);
   return err;
 }
 
 
 int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
   int err;
-  CALLBACK_MAYBE(s, on_message_complete, s);
+  CALLBACK_MAYBE(s, on_message_complete);
   return err;
 }
 
 
 int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
   int err;
-  CALLBACK_MAYBE(s, on_body, s, p, endp - p);
+  SPAN_CALLBACK_MAYBE(s, on_body, p, endp - p);
   return err;
 }
 
 
 int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
   int err;
-  CALLBACK_MAYBE(s, on_chunk_header, s);
+  CALLBACK_MAYBE(s, on_chunk_header);
   return err;
 }
 
 
 int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
   int err;
-  CALLBACK_MAYBE(s, on_chunk_complete, s);
+  CALLBACK_MAYBE(s, on_chunk_complete);
   return err;
 }
 
index 6e4906d..e6279f3 100644 (file)
@@ -51,7 +51,8 @@ int llhttp__after_headers_complete(llhttp_t* parser, const char* p,
     /* chunked encoding - ignore Content-Length header, prepare for a chunk */
     return 2;
   } else if (parser->flags & F_TRANSFER_ENCODING) {
-    if (parser->type == HTTP_REQUEST && (parser->flags & F_LENIENT) == 0) {
+    if (parser->type == HTTP_REQUEST &&
+        (parser->lenient_flags & LENIENT_CHUNKED_LENGTH) == 0) {
       /* RFC 7230 3.3.3 */
 
       /* If a Transfer-Encoding header field
@@ -97,9 +98,7 @@ int llhttp__after_message_complete(llhttp_t* parser, const char* p,
 
   should_keep_alive = llhttp_should_keep_alive(parser);
   parser->finish = HTTP_FINISH_SAFE;
-
-  /* Keep `F_LENIENT` flag between messages, but reset every other flag */
-  parser->flags &= F_LENIENT;
+  parser->flags = 0;
 
   /* NOTE: this is ignored in loose parsing mode */
   return should_keep_alive;
index 2a44fa6..a8efce1 100644 (file)
@@ -1,3 +1,5 @@
+#if LLHTTP_STRICT_MODE
+
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
@@ -22,173 +24,197 @@ typedef int (*llhttp__internal__span_cb)(
              llhttp__internal_t*, const char*, const char*);
 
 static const unsigned char llparse_blob0[] = {
-  'C', 'L'
+  0xd, 0xa
 };
-#ifdef __SSE4_2__
-static const unsigned char ALIGN(16) llparse_blob1[] = {
-  0x9, 0x9, 0xc, 0xc, '!', '"', '$', '>', '@', '~', 0x80,
-  0xff, 0x0, 0x0, 0x0, 0x0
+static const unsigned char llparse_blob1[] = {
+  'o', 'n'
 };
-#endif  /* __SSE4_2__ */
 static const unsigned char llparse_blob2[] = {
-  'o', 'n'
+  'e', 'c', 't', 'i', 'o', 'n'
 };
 static const unsigned char llparse_blob3[] = {
-  'e', 'c', 't', 'i', 'o', 'n'
+  'l', 'o', 's', 'e'
 };
 static const unsigned char llparse_blob4[] = {
-  'l', 'o', 's', 'e'
+  'e', 'e', 'p', '-', 'a', 'l', 'i', 'v', 'e'
 };
 static const unsigned char llparse_blob5[] = {
-  'e', 'e', 'p', '-', 'a', 'l', 'i', 'v', 'e'
+  'p', 'g', 'r', 'a', 'd', 'e'
 };
 static const unsigned char llparse_blob6[] = {
-  'p', 'g', 'r', 'a', 'd', 'e'
+  'c', 'h', 'u', 'n', 'k', 'e', 'd'
 };
 #ifdef __SSE4_2__
 static const unsigned char ALIGN(16) llparse_blob7[] = {
-  0x9, 0x9, ' ', '~', 0x80, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0,
+  0x9, 0x9, ' ', '~', 0x80, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0,
   0x0, 0x0, 0x0, 0x0, 0x0
 };
 #endif  /* __SSE4_2__ */
-static const unsigned char llparse_blob8[] = {
-  'c', 'h', 'u', 'n', 'k', 'e', 'd'
-};
 #ifdef __SSE4_2__
-static const unsigned char ALIGN(16) llparse_blob9[] = {
-  ' ', '!', '#', '\'', '*', '+', '-', '.', '0', '9', 'A',
+static const unsigned char ALIGN(16) llparse_blob8[] = {
+  '!', '!', '#', '\'', '*', '+', '-', '.', '0', '9', 'A',
   'Z', '^', 'z', '|', '|'
 };
 #endif  /* __SSE4_2__ */
 #ifdef __SSE4_2__
-static const unsigned char ALIGN(16) llparse_blob10[] = {
+static const unsigned char ALIGN(16) llparse_blob9[] = {
   '~', '~', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   0x0, 0x0, 0x0, 0x0, 0x0
 };
 #endif  /* __SSE4_2__ */
-static const unsigned char llparse_blob11[] = {
+static const unsigned char llparse_blob10[] = {
   'e', 'n', 't', '-', 'l', 'e', 'n', 'g', 't', 'h'
 };
-static const unsigned char llparse_blob12[] = {
+static const unsigned char llparse_blob11[] = {
   'r', 'o', 'x', 'y', '-', 'c', 'o', 'n', 'n', 'e', 'c',
   't', 'i', 'o', 'n'
 };
-static const unsigned char llparse_blob13[] = {
+static const unsigned char llparse_blob12[] = {
   'r', 'a', 'n', 's', 'f', 'e', 'r', '-', 'e', 'n', 'c',
   'o', 'd', 'i', 'n', 'g'
 };
-static const unsigned char llparse_blob14[] = {
+static const unsigned char llparse_blob13[] = {
   'p', 'g', 'r', 'a', 'd', 'e'
 };
+static const unsigned char llparse_blob14[] = {
+  'T', 'T', 'P', '/'
+};
 static const unsigned char llparse_blob15[] = {
-  0xd, 0xa
+  0xd, 0xa, 0xd, 0xa, 'S', 'M', 0xd, 0xa, 0xd, 0xa
 };
 static const unsigned char llparse_blob16[] = {
-  'T', 'T', 'P', '/'
+  'C', 'E', '/'
 };
 static const unsigned char llparse_blob17[] = {
-  'C', 'E', '/'
+  'T', 'S', 'P', '/'
 };
 static const unsigned char llparse_blob18[] = {
-  'I', 'N', 'D'
+  'N', 'O', 'U', 'N', 'C', 'E'
 };
 static const unsigned char llparse_blob19[] = {
-  'E', 'C', 'K', 'O', 'U', 'T'
+  'I', 'N', 'D'
 };
 static const unsigned char llparse_blob20[] = {
-  'N', 'E', 'C', 'T'
+  'E', 'C', 'K', 'O', 'U', 'T'
 };
 static const unsigned char llparse_blob21[] = {
-  'E', 'L', 'E', 'T', 'E'
+  'N', 'E', 'C', 'T'
 };
 static const unsigned char llparse_blob22[] = {
-  'E', 'T'
+  'E', 'T', 'E'
 };
 static const unsigned char llparse_blob23[] = {
-  'E', 'A', 'D'
+  'C', 'R', 'I', 'B', 'E'
 };
 static const unsigned char llparse_blob24[] = {
-  'N', 'K'
+  'L', 'U', 'S', 'H'
 };
 static const unsigned char llparse_blob25[] = {
-  'C', 'K'
+  'E', 'T'
 };
 static const unsigned char llparse_blob26[] = {
-  'S', 'E', 'A', 'R', 'C', 'H'
+  'P', 'A', 'R', 'A', 'M', 'E', 'T', 'E', 'R'
 };
 static const unsigned char llparse_blob27[] = {
-  'R', 'G', 'E'
+  'E', 'A', 'D'
 };
 static const unsigned char llparse_blob28[] = {
-  'C', 'T', 'I', 'V', 'I', 'T', 'Y'
+  'N', 'K'
 };
 static const unsigned char llparse_blob29[] = {
-  'L', 'E', 'N', 'D', 'A', 'R'
+  'C', 'K'
 };
 static const unsigned char llparse_blob30[] = {
-  'V', 'E'
+  'S', 'E', 'A', 'R', 'C', 'H'
 };
 static const unsigned char llparse_blob31[] = {
-  'O', 'T', 'I', 'F', 'Y'
+  'R', 'G', 'E'
 };
 static const unsigned char llparse_blob32[] = {
-  'P', 'T', 'I', 'O', 'N', 'S'
+  'C', 'T', 'I', 'V', 'I', 'T', 'Y'
 };
 static const unsigned char llparse_blob33[] = {
-  'T', 'C', 'H'
+  'L', 'E', 'N', 'D', 'A', 'R'
 };
 static const unsigned char llparse_blob34[] = {
-  'S', 'T'
+  'V', 'E'
 };
 static const unsigned char llparse_blob35[] = {
-  'O', 'P'
+  'O', 'T', 'I', 'F', 'Y'
 };
 static const unsigned char llparse_blob36[] = {
-  'I', 'N', 'D'
+  'P', 'T', 'I', 'O', 'N', 'S'
 };
 static const unsigned char llparse_blob37[] = {
-  'A', 'T', 'C', 'H'
+  'C', 'H'
 };
 static const unsigned char llparse_blob38[] = {
-  'G', 'E'
+  'S', 'E'
 };
 static const unsigned char llparse_blob39[] = {
-  'I', 'N', 'D'
+  'A', 'Y'
 };
 static const unsigned char llparse_blob40[] = {
-  'O', 'R', 'T'
+  'S', 'T'
 };
 static const unsigned char llparse_blob41[] = {
-  'A', 'R', 'C', 'H'
+  'I', 'N', 'D'
 };
 static const unsigned char llparse_blob42[] = {
-  'U', 'R', 'C', 'E'
+  'A', 'T', 'C', 'H'
 };
 static const unsigned char llparse_blob43[] = {
-  'B', 'S', 'C', 'R', 'I', 'B', 'E'
+  'G', 'E'
 };
 static const unsigned char llparse_blob44[] = {
-  'R', 'A', 'C', 'E'
+  'I', 'N', 'D'
 };
 static const unsigned char llparse_blob45[] = {
-  'I', 'N', 'D'
+  'O', 'R', 'D'
 };
 static const unsigned char llparse_blob46[] = {
-  'N', 'K'
+  'I', 'R', 'E', 'C', 'T'
 };
 static const unsigned char llparse_blob47[] = {
-  'C', 'K'
+  'O', 'R', 'T'
 };
 static const unsigned char llparse_blob48[] = {
-  'U', 'B', 'S', 'C', 'R', 'I', 'B', 'E'
+  'R', 'C', 'H'
 };
 static const unsigned char llparse_blob49[] = {
-  'H', 'T', 'T', 'P', '/'
+  'P', 'A', 'R', 'A', 'M', 'E', 'T', 'E', 'R'
 };
 static const unsigned char llparse_blob50[] = {
-  'A', 'D'
+  'U', 'R', 'C', 'E'
 };
 static const unsigned char llparse_blob51[] = {
+  'B', 'S', 'C', 'R', 'I', 'B', 'E'
+};
+static const unsigned char llparse_blob52[] = {
+  'A', 'R', 'D', 'O', 'W', 'N'
+};
+static const unsigned char llparse_blob53[] = {
+  'A', 'C', 'E'
+};
+static const unsigned char llparse_blob54[] = {
+  'I', 'N', 'D'
+};
+static const unsigned char llparse_blob55[] = {
+  'N', 'K'
+};
+static const unsigned char llparse_blob56[] = {
+  'C', 'K'
+};
+static const unsigned char llparse_blob57[] = {
+  'U', 'B', 'S', 'C', 'R', 'I', 'B', 'E'
+};
+static const unsigned char llparse_blob58[] = {
+  'H', 'T', 'T', 'P', '/'
+};
+static const unsigned char llparse_blob59[] = {
+  'A', 'D'
+};
+static const unsigned char llparse_blob60[] = {
   'T', 'P', '/'
 };
 
@@ -237,6 +263,38 @@ reset:
   return res;
 }
 
+static llparse_match_t llparse__match_sequence_to_lower(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp,
+    const unsigned char* seq, uint32_t seq_len) {
+  uint32_t index;
+  llparse_match_t res;
+
+  index = s->_index;
+  for (; p != endp; p++) {
+    unsigned char current;
+
+    current = ((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p));
+    if (current == seq[index]) {
+      if (++index == seq_len) {
+        res.status = kMatchComplete;
+        goto reset;
+      }
+    } else {
+      res.status = kMatchMismatch;
+      goto reset;
+    }
+  }
+  s->_index = index;
+  res.status = kMatchPause;
+  res.current = p;
+  return res;
+reset:
+  s->_index = 0;
+  res.current = p;
+  return res;
+}
+
 static llparse_match_t llparse__match_sequence_to_lower_unsafe(
     llhttp__internal_t* s, const unsigned char* p,
     const unsigned char* endp,
@@ -271,11 +329,11 @@ reset:
 
 enum llparse_state_e {
   s_error,
+  s_n_llhttp__internal__n_closed,
   s_n_llhttp__internal__n_invoke_llhttp__after_message_complete,
   s_n_llhttp__internal__n_pause_1,
   s_n_llhttp__internal__n_invoke_is_equal_upgrade,
   s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2,
-  s_n_llhttp__internal__n_chunk_data_almost_done_skip,
   s_n_llhttp__internal__n_chunk_data_almost_done,
   s_n_llhttp__internal__n_consume_content_length,
   s_n_llhttp__internal__n_span_start_llhttp__on_body,
@@ -292,6 +350,7 @@ enum llparse_state_e {
   s_n_llhttp__internal__n_span_start_llhttp__on_body_2,
   s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete,
   s_n_llhttp__internal__n_headers_almost_done,
+  s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete,
   s_n_llhttp__internal__n_span_start_llhttp__on_header_value,
   s_n_llhttp__internal__n_header_value_discard_lws,
   s_n_llhttp__internal__n_header_value_discard_ws_almost_done,
@@ -305,18 +364,18 @@ enum llparse_state_e {
   s_n_llhttp__internal__n_header_value_connection_2,
   s_n_llhttp__internal__n_header_value_connection_3,
   s_n_llhttp__internal__n_header_value_connection,
-  s_n_llhttp__internal__n_error_18,
-  s_n_llhttp__internal__n_header_value,
-  s_n_llhttp__internal__n_header_value_discard_rws,
-  s_n_llhttp__internal__n_error_19,
+  s_n_llhttp__internal__n_error_23,
+  s_n_llhttp__internal__n_error_24,
   s_n_llhttp__internal__n_header_value_content_length_ws,
   s_n_llhttp__internal__n_header_value_content_length,
   s_n_llhttp__internal__n_header_value_te_chunked_last,
   s_n_llhttp__internal__n_header_value_te_token_ows,
+  s_n_llhttp__internal__n_header_value,
   s_n_llhttp__internal__n_header_value_te_token,
   s_n_llhttp__internal__n_header_value_te_chunked,
   s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1,
   s_n_llhttp__internal__n_header_value_discard_ws,
+  s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete,
   s_n_llhttp__internal__n_header_field_general_otherwise,
   s_n_llhttp__internal__n_header_field_general,
   s_n_llhttp__internal__n_header_field_colon,
@@ -330,16 +389,21 @@ enum llparse_state_e {
   s_n_llhttp__internal__n_header_field,
   s_n_llhttp__internal__n_span_start_llhttp__on_header_field,
   s_n_llhttp__internal__n_header_field_start,
+  s_n_llhttp__internal__n_url_to_http_09,
   s_n_llhttp__internal__n_url_skip_to_http09,
+  s_n_llhttp__internal__n_url_skip_lf_to_http09_1,
   s_n_llhttp__internal__n_url_skip_lf_to_http09,
-  s_n_llhttp__internal__n_req_http_end_1,
-  s_n_llhttp__internal__n_req_http_end,
+  s_n_llhttp__internal__n_req_pri_upgrade,
+  s_n_llhttp__internal__n_req_http_complete_1,
+  s_n_llhttp__internal__n_req_http_complete,
   s_n_llhttp__internal__n_req_http_minor,
   s_n_llhttp__internal__n_req_http_dot,
   s_n_llhttp__internal__n_req_http_major,
   s_n_llhttp__internal__n_req_http_start_1,
   s_n_llhttp__internal__n_req_http_start_2,
+  s_n_llhttp__internal__n_req_http_start_3,
   s_n_llhttp__internal__n_req_http_start,
+  s_n_llhttp__internal__n_url_to_http,
   s_n_llhttp__internal__n_url_skip_to_http,
   s_n_llhttp__internal__n_url_fragment,
   s_n_llhttp__internal__n_span_end_stub_query_3,
@@ -357,59 +421,82 @@ enum llparse_state_e {
   s_n_llhttp__internal__n_url_schema,
   s_n_llhttp__internal__n_url_start,
   s_n_llhttp__internal__n_span_start_llhttp__on_url_1,
+  s_n_llhttp__internal__n_url_entry_normal,
   s_n_llhttp__internal__n_span_start_llhttp__on_url,
+  s_n_llhttp__internal__n_url_entry_connect,
   s_n_llhttp__internal__n_req_spaces_before_url,
   s_n_llhttp__internal__n_req_first_space_before_url,
-  s_n_llhttp__internal__n_start_req_1,
   s_n_llhttp__internal__n_start_req_2,
+  s_n_llhttp__internal__n_start_req_3,
+  s_n_llhttp__internal__n_start_req_1,
   s_n_llhttp__internal__n_start_req_4,
   s_n_llhttp__internal__n_start_req_6,
-  s_n_llhttp__internal__n_start_req_7,
-  s_n_llhttp__internal__n_start_req_5,
-  s_n_llhttp__internal__n_start_req_3,
   s_n_llhttp__internal__n_start_req_8,
   s_n_llhttp__internal__n_start_req_9,
-  s_n_llhttp__internal__n_start_req_10,
+  s_n_llhttp__internal__n_start_req_7,
+  s_n_llhttp__internal__n_start_req_5,
   s_n_llhttp__internal__n_start_req_12,
   s_n_llhttp__internal__n_start_req_13,
   s_n_llhttp__internal__n_start_req_11,
-  s_n_llhttp__internal__n_start_req_15,
+  s_n_llhttp__internal__n_start_req_10,
+  s_n_llhttp__internal__n_start_req_14,
+  s_n_llhttp__internal__n_start_req_17,
   s_n_llhttp__internal__n_start_req_16,
+  s_n_llhttp__internal__n_start_req_15,
   s_n_llhttp__internal__n_start_req_18,
   s_n_llhttp__internal__n_start_req_20,
   s_n_llhttp__internal__n_start_req_21,
   s_n_llhttp__internal__n_start_req_19,
-  s_n_llhttp__internal__n_start_req_17,
-  s_n_llhttp__internal__n_start_req_22,
-  s_n_llhttp__internal__n_start_req_14,
   s_n_llhttp__internal__n_start_req_23,
   s_n_llhttp__internal__n_start_req_24,
   s_n_llhttp__internal__n_start_req_26,
+  s_n_llhttp__internal__n_start_req_28,
+  s_n_llhttp__internal__n_start_req_29,
   s_n_llhttp__internal__n_start_req_27,
+  s_n_llhttp__internal__n_start_req_25,
   s_n_llhttp__internal__n_start_req_30,
+  s_n_llhttp__internal__n_start_req_22,
   s_n_llhttp__internal__n_start_req_31,
-  s_n_llhttp__internal__n_start_req_29,
-  s_n_llhttp__internal__n_start_req_28,
-  s_n_llhttp__internal__n_start_req_33,
   s_n_llhttp__internal__n_start_req_32,
-  s_n_llhttp__internal__n_start_req_25,
-  s_n_llhttp__internal__n_start_req_36,
-  s_n_llhttp__internal__n_start_req_37,
   s_n_llhttp__internal__n_start_req_35,
+  s_n_llhttp__internal__n_start_req_36,
   s_n_llhttp__internal__n_start_req_34,
-  s_n_llhttp__internal__n_start_req_39,
-  s_n_llhttp__internal__n_start_req_40,
-  s_n_llhttp__internal__n_start_req_41,
+  s_n_llhttp__internal__n_start_req_37,
   s_n_llhttp__internal__n_start_req_38,
   s_n_llhttp__internal__n_start_req_42,
+  s_n_llhttp__internal__n_start_req_43,
+  s_n_llhttp__internal__n_start_req_41,
+  s_n_llhttp__internal__n_start_req_40,
+  s_n_llhttp__internal__n_start_req_39,
   s_n_llhttp__internal__n_start_req_45,
-  s_n_llhttp__internal__n_start_req_47,
+  s_n_llhttp__internal__n_start_req_44,
+  s_n_llhttp__internal__n_start_req_33,
   s_n_llhttp__internal__n_start_req_48,
-  s_n_llhttp__internal__n_start_req_46,
   s_n_llhttp__internal__n_start_req_49,
-  s_n_llhttp__internal__n_start_req_44,
-  s_n_llhttp__internal__n_start_req_43,
+  s_n_llhttp__internal__n_start_req_50,
+  s_n_llhttp__internal__n_start_req_51,
+  s_n_llhttp__internal__n_start_req_47,
+  s_n_llhttp__internal__n_start_req_46,
+  s_n_llhttp__internal__n_start_req_54,
+  s_n_llhttp__internal__n_start_req_56,
+  s_n_llhttp__internal__n_start_req_57,
+  s_n_llhttp__internal__n_start_req_55,
+  s_n_llhttp__internal__n_start_req_53,
+  s_n_llhttp__internal__n_start_req_58,
+  s_n_llhttp__internal__n_start_req_59,
+  s_n_llhttp__internal__n_start_req_52,
+  s_n_llhttp__internal__n_start_req_61,
+  s_n_llhttp__internal__n_start_req_62,
+  s_n_llhttp__internal__n_start_req_60,
+  s_n_llhttp__internal__n_start_req_65,
+  s_n_llhttp__internal__n_start_req_67,
+  s_n_llhttp__internal__n_start_req_68,
+  s_n_llhttp__internal__n_start_req_66,
+  s_n_llhttp__internal__n_start_req_69,
+  s_n_llhttp__internal__n_start_req_64,
+  s_n_llhttp__internal__n_start_req_63,
   s_n_llhttp__internal__n_start_req,
+  s_n_llhttp__internal__n_invoke_llhttp__on_status_complete,
   s_n_llhttp__internal__n_res_line_almost_done,
   s_n_llhttp__internal__n_res_status,
   s_n_llhttp__internal__n_span_start_llhttp__on_status,
@@ -502,6 +589,10 @@ int llhttp__internal__c_update_http_minor(
   return 0;
 }
 
+int llhttp__on_url_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
 int llhttp__internal__c_test_flags(
     llhttp__internal_t* state,
     const unsigned char* p,
@@ -536,25 +627,25 @@ int llhttp__internal__c_update_finish_1(
   return 0;
 }
 
-int llhttp__internal__c_test_flags_1(
+int llhttp__internal__c_test_lenient_flags(
     llhttp__internal_t* state,
     const unsigned char* p,
     const unsigned char* endp) {
-  return (state->flags & 544) == 544;
+  return (state->lenient_flags & 4) == 4;
 }
 
-int llhttp__internal__c_test_flags_2(
+int llhttp__internal__c_test_flags_1(
     llhttp__internal_t* state,
     const unsigned char* p,
     const unsigned char* endp) {
-  return (state->flags & 256) == 256;
+  return (state->flags & 544) == 544;
 }
 
-int llhttp__internal__c_test_flags_3(
+int llhttp__internal__c_test_lenient_flags_1(
     llhttp__internal_t* state,
     const unsigned char* p,
     const unsigned char* endp) {
-  return (state->flags & 40) == 40;
+  return (state->lenient_flags & 2) == 2;
 }
 
 int llhttp__before_headers_complete(
@@ -622,7 +713,7 @@ int llhttp__internal__c_or_flags(
   return 0;
 }
 
-int llhttp__internal__c_update_finish_2(
+int llhttp__internal__c_update_finish_3(
     llhttp__internal_t* state,
     const unsigned char* p,
     const unsigned char* endp) {
@@ -655,6 +746,10 @@ int llhttp__internal__c_store_header_state(
   return 0;
 }
 
+int llhttp__on_header_field_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
 int llhttp__internal__c_load_header_state(
     llhttp__internal_t* state,
     const unsigned char* p,
@@ -678,6 +773,10 @@ int llhttp__internal__c_update_header_state(
   return 0;
 }
 
+int llhttp__on_header_value_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
 int llhttp__internal__c_or_flags_4(
     llhttp__internal_t* state,
     const unsigned char* p,
@@ -710,6 +809,13 @@ int llhttp__internal__c_update_header_state_2(
   return 0;
 }
 
+int llhttp__internal__c_test_lenient_flags_2(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return (state->lenient_flags & 1) == 1;
+}
+
 int llhttp__internal__c_update_header_state_4(
     llhttp__internal_t* state,
     const unsigned char* p,
@@ -734,7 +840,7 @@ int llhttp__internal__c_update_header_state_6(
   return 0;
 }
 
-int llhttp__internal__c_test_flags_5(
+int llhttp__internal__c_test_flags_2(
     llhttp__internal_t* state,
     const unsigned char* p,
     const unsigned char* endp) {
@@ -783,7 +889,15 @@ int llhttp__internal__c_or_flags_16(
   return 0;
 }
 
-int llhttp__internal__c_update_header_state_8(
+int llhttp__internal__c_and_flags(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags &= -9;
+  return 0;
+}
+
+int llhttp__internal__c_update_header_state_7(
     llhttp__internal_t* state,
     const unsigned char* p,
     const unsigned char* endp) {
@@ -799,6 +913,13 @@ int llhttp__internal__c_or_flags_17(
   return 0;
 }
 
+int llhttp__internal__c_load_method(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return state->method;
+}
+
 int llhttp__internal__c_store_http_major(
     llhttp__internal_t* state,
     const unsigned char* p,
@@ -817,13 +938,6 @@ int llhttp__internal__c_store_http_minor(
   return 0;
 }
 
-int llhttp__internal__c_is_equal_method_1(
-    llhttp__internal_t* state,
-    const unsigned char* p,
-    const unsigned char* endp) {
-  return state->method == 33;
-}
-
 int llhttp__internal__c_update_status_code(
     llhttp__internal_t* state,
     const unsigned char* p,
@@ -863,6 +977,10 @@ int llhttp__internal__c_mul_add_status_code(
   return 0;
 }
 
+int llhttp__on_status_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
 int llhttp__internal__c_update_type(
     llhttp__internal_t* state,
     const unsigned char* p,
@@ -891,9 +1009,33 @@ static llparse_state_t llhttp__internal__run(
     const unsigned char* endp) {
   int match;
   switch ((llparse_state_t) (intptr_t) state->_current) {
+    case s_n_llhttp__internal__n_closed:
+    s_n_llhttp__internal__n_closed: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_closed;
+      }
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_closed;
+        }
+        case 13: {
+          p++;
+          goto s_n_llhttp__internal__n_closed;
+        }
+        default: {
+          p++;
+          goto s_n_llhttp__internal__n_error_4;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
     case s_n_llhttp__internal__n_invoke_llhttp__after_message_complete:
     s_n_llhttp__internal__n_invoke_llhttp__after_message_complete: {
       switch (llhttp__after_message_complete(state, p, endp)) {
+        case 1:
+          goto s_n_llhttp__internal__n_invoke_update_finish_2;
         default:
           goto s_n_llhttp__internal__n_invoke_update_finish_1;
       }
@@ -929,33 +1071,37 @@ static llparse_state_t llhttp__internal__run(
         case 21:
           goto s_n_llhttp__internal__n_pause_5;
         default:
-          goto s_n_llhttp__internal__n_error_9;
-      }
-      /* UNREACHABLE */;
-      abort();
-    }
-    case s_n_llhttp__internal__n_chunk_data_almost_done_skip:
-    s_n_llhttp__internal__n_chunk_data_almost_done_skip: {
-      if (p == endp) {
-        return s_n_llhttp__internal__n_chunk_data_almost_done_skip;
+          goto s_n_llhttp__internal__n_error_13;
       }
-      p++;
-      goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete;
       /* UNREACHABLE */;
       abort();
     }
     case s_n_llhttp__internal__n_chunk_data_almost_done:
     s_n_llhttp__internal__n_chunk_data_almost_done: {
+      llparse_match_t match_seq;
+      
       if (p == endp) {
         return s_n_llhttp__internal__n_chunk_data_almost_done;
       }
-      p++;
-      goto s_n_llhttp__internal__n_chunk_data_almost_done_skip;
-      /* UNREACHABLE */;
-      abort();
-    }
-    case s_n_llhttp__internal__n_consume_content_length:
-    s_n_llhttp__internal__n_consume_content_length: {
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob0, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_chunk_data_almost_done;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_8;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_consume_content_length:
+    s_n_llhttp__internal__n_consume_content_length: {
       size_t avail;
       size_t need;
       
@@ -999,8 +1145,15 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_chunk_size_almost_done;
       }
-      p++;
-      goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_header;
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_header;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_9;
+        }
+      }
       /* UNREACHABLE */;
       abort();
     }
@@ -1041,7 +1194,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_chunk_parameters;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_6;
+          goto s_n_llhttp__internal__n_error_10;
         }
       }
       /* UNREACHABLE */;
@@ -1287,7 +1440,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_8;
+          goto s_n_llhttp__internal__n_error_12;
         }
       }
       /* UNREACHABLE */;
@@ -1362,9 +1515,9 @@ static llparse_state_t llhttp__internal__run(
         case 3:
           goto s_n_llhttp__internal__n_span_start_llhttp__on_body_1;
         case 4:
-          goto s_n_llhttp__internal__n_invoke_update_finish_2;
+          goto s_n_llhttp__internal__n_invoke_update_finish_3;
         case 5:
-          goto s_n_llhttp__internal__n_error_10;
+          goto s_n_llhttp__internal__n_error_14;
         default:
           goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete;
       }
@@ -1376,8 +1529,24 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_headers_almost_done;
       }
-      p++;
-      goto s_n_llhttp__internal__n_invoke_test_flags;
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_test_flags;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_17;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete:
+    s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete: {
+      switch (llhttp__on_header_value_complete(state, p, endp)) {
+        default:
+          goto s_n_llhttp__internal__n_header_field_start;
+      }
       /* UNREACHABLE */;
       abort();
     }
@@ -1418,8 +1587,15 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_value_discard_ws_almost_done;
       }
-      p++;
-      goto s_n_llhttp__internal__n_header_value_discard_lws;
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_discard_lws;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_19;
+        }
+      }
       /* UNREACHABLE */;
       abort();
     }
@@ -1453,7 +1629,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_header_value_lws;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_15;
+          goto s_n_llhttp__internal__n_error_20;
         }
       }
       /* UNREACHABLE */;
@@ -1492,7 +1668,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_2;
         }
         default: {
-          goto s_n_llhttp__internal__n_invoke_test_flags_4;
+          goto s_n_llhttp__internal__n_invoke_test_lenient_flags_2;
         }
       }
       /* UNREACHABLE */;
@@ -1516,7 +1692,7 @@ static llparse_state_t llhttp__internal__run(
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
       };
       if (p == endp) {
         return s_n_llhttp__internal__n_header_value_connection_token;
@@ -1571,7 +1747,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_value_connection_1;
       }
-      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob4, 4);
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob3, 4);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -1595,7 +1771,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_value_connection_2;
       }
-      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob5, 9);
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob4, 9);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -1619,7 +1795,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_value_connection_3;
       }
-      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob6, 6);
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob5, 6);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -1641,7 +1817,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_value_connection;
       }
-      switch (((*p) | 0x20)) {
+      switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) {
         case 9: {
           p++;
           goto s_n_llhttp__internal__n_header_value_connection;
@@ -1669,8 +1845,8 @@ static llparse_state_t llhttp__internal__run(
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_error_18:
-    s_n_llhttp__internal__n_error_18: {
+    case s_n_llhttp__internal__n_error_23:
+    s_n_llhttp__internal__n_error_23: {
       state->error = 0xb;
       state->reason = "Content-Length overflow";
       state->error_pos = (const char*) p;
@@ -1679,90 +1855,8 @@ static llparse_state_t llhttp__internal__run(
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_header_value:
-    s_n_llhttp__internal__n_header_value: {
-      static uint8_t lookup_table[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
-      };
-      if (p == endp) {
-        return s_n_llhttp__internal__n_header_value;
-      }
-      #ifdef __SSE4_2__
-      if (endp - p >= 16) {
-        __m128i ranges;
-        __m128i input;
-        int avail;
-        int match_len;
-      
-        /* Load input */
-        input = _mm_loadu_si128((__m128i const*) p);
-        ranges = _mm_loadu_si128((__m128i const*) llparse_blob7);
-      
-        /* Find first character that does not match `ranges` */
-        match_len = _mm_cmpestri(ranges, 6,
-            input, 16,
-            _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
-              _SIDD_NEGATIVE_POLARITY);
-      
-        if (match_len != 0) {
-          p += match_len;
-          goto s_n_llhttp__internal__n_header_value;
-        }
-        goto s_n_llhttp__internal__n_header_value_otherwise;
-      }
-      #endif  /* __SSE4_2__ */
-      switch (lookup_table[(uint8_t) *p]) {
-        case 1: {
-          p++;
-          goto s_n_llhttp__internal__n_header_value;
-        }
-        default: {
-          goto s_n_llhttp__internal__n_header_value_otherwise;
-        }
-      }
-      /* UNREACHABLE */;
-      abort();
-    }
-    case s_n_llhttp__internal__n_header_value_discard_rws:
-    s_n_llhttp__internal__n_header_value_discard_rws: {
-      if (p == endp) {
-        return s_n_llhttp__internal__n_header_value_discard_rws;
-      }
-      switch (*p) {
-        case 10: {
-          goto s_n_llhttp__internal__n_header_value_otherwise;
-        }
-        case 13: {
-          goto s_n_llhttp__internal__n_header_value_otherwise;
-        }
-        case ' ': {
-          p++;
-          goto s_n_llhttp__internal__n_header_value_discard_rws;
-        }
-        default: {
-          goto s_n_llhttp__internal__n_invoke_update_header_state_7;
-        }
-      }
-      /* UNREACHABLE */;
-      abort();
-    }
-    case s_n_llhttp__internal__n_error_19:
-    s_n_llhttp__internal__n_error_19: {
+    case s_n_llhttp__internal__n_error_24:
+    s_n_llhttp__internal__n_error_24: {
       state->error = 0xb;
       state->reason = "Invalid character in Content-Length";
       state->error_pos = (const char*) p;
@@ -1864,10 +1958,10 @@ static llparse_state_t llhttp__internal__run(
       }
       switch (*p) {
         case 10: {
-          goto s_n_llhttp__internal__n_invoke_update_header_state_8;
+          goto s_n_llhttp__internal__n_invoke_update_header_state_7;
         }
         case 13: {
-          goto s_n_llhttp__internal__n_invoke_update_header_state_8;
+          goto s_n_llhttp__internal__n_invoke_update_header_state_7;
         }
         case ' ': {
           p++;
@@ -1901,6 +1995,65 @@ static llparse_state_t llhttp__internal__run(
       /* UNREACHABLE */;
       abort();
     }
+    case s_n_llhttp__internal__n_header_value:
+    s_n_llhttp__internal__n_header_value: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value;
+      }
+      #ifdef __SSE4_2__
+      if (endp - p >= 16) {
+        __m128i ranges;
+        __m128i input;
+        int avail;
+        int match_len;
+      
+        /* Load input */
+        input = _mm_loadu_si128((__m128i const*) p);
+        ranges = _mm_loadu_si128((__m128i const*) llparse_blob7);
+      
+        /* Find first character that does not match `ranges` */
+        match_len = _mm_cmpestri(ranges, 6,
+            input, 16,
+            _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
+              _SIDD_NEGATIVE_POLARITY);
+      
+        if (match_len != 0) {
+          p += match_len;
+          goto s_n_llhttp__internal__n_header_value;
+        }
+        goto s_n_llhttp__internal__n_header_value_otherwise;
+      }
+      #endif  /* __SSE4_2__ */
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_header_value_otherwise;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
     case s_n_llhttp__internal__n_header_value_te_token:
     s_n_llhttp__internal__n_header_value_te_token: {
       static uint8_t lookup_table[] = {
@@ -1919,7 +2072,7 @@ static llparse_state_t llhttp__internal__run(
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
       };
       if (p == endp) {
         return s_n_llhttp__internal__n_header_value_te_token;
@@ -1934,7 +2087,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_header_value_te_token_ows;
         }
         default: {
-          goto s_n_llhttp__internal__n_invoke_update_header_state_7;
+          goto s_n_llhttp__internal__n_invoke_update_header_state_8;
         }
       }
       /* UNREACHABLE */;
@@ -1947,7 +2100,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_value_te_chunked;
       }
-      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob8, 7);
+      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob6, 7);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -2004,6 +2157,15 @@ static llparse_state_t llhttp__internal__run(
       /* UNREACHABLE */;
       abort();
     }
+    case s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete:
+    s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete: {
+      switch (llhttp__on_header_field_complete(state, p, endp)) {
+        default:
+          goto s_n_llhttp__internal__n_header_value_discard_ws;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
     case s_n_llhttp__internal__n_header_field_general_otherwise:
     s_n_llhttp__internal__n_header_field_general_otherwise: {
       if (p == endp) {
@@ -2014,7 +2176,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_span_end_llhttp__on_header_field_1;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_20;
+          goto s_n_llhttp__internal__n_error_25;
         }
       }
       /* UNREACHABLE */;
@@ -2025,7 +2187,7 @@ static llparse_state_t llhttp__internal__run(
       static uint8_t lookup_table[] = {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
+        0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
@@ -2052,7 +2214,7 @@ static llparse_state_t llhttp__internal__run(
       
         /* Load input */
         input = _mm_loadu_si128((__m128i const*) p);
-        ranges = _mm_loadu_si128((__m128i const*) llparse_blob9);
+        ranges = _mm_loadu_si128((__m128i const*) llparse_blob8);
       
         /* Find first character that does not match `ranges` */
         match_len = _mm_cmpestri(ranges, 16,
@@ -2064,7 +2226,7 @@ static llparse_state_t llhttp__internal__run(
           p += match_len;
           goto s_n_llhttp__internal__n_header_field_general;
         }
-        ranges = _mm_loadu_si128((__m128i const*) llparse_blob10);
+        ranges = _mm_loadu_si128((__m128i const*) llparse_blob9);
       
         /* Find first character that does not match `ranges` */
         match_len = _mm_cmpestri(ranges, 2,
@@ -2118,7 +2280,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_field_3;
       }
-      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob3, 6);
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob2, 6);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -2143,7 +2305,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_field_4;
       }
-      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob11, 10);
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob10, 10);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -2166,7 +2328,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_field_2;
       }
-      switch (((*p) | 0x20)) {
+      switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) {
         case 'n': {
           p++;
           goto s_n_llhttp__internal__n_header_field_3;
@@ -2189,7 +2351,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_field_1;
       }
-      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob2, 2);
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob1, 2);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -2213,7 +2375,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_field_5;
       }
-      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob12, 15);
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob11, 15);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -2238,7 +2400,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_field_6;
       }
-      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob13, 16);
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob12, 16);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -2263,7 +2425,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_field_7;
       }
-      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob14, 6);
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob13, 6);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -2286,7 +2448,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_header_field;
       }
-      switch (((*p) | 0x20)) {
+      switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) {
         case 'c': {
           p++;
           goto s_n_llhttp__internal__n_header_field_1;
@@ -2341,73 +2503,148 @@ static llparse_state_t llhttp__internal__run(
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_url_skip_to_http09:
-    s_n_llhttp__internal__n_url_skip_to_http09: {
+    case s_n_llhttp__internal__n_url_to_http_09:
+    s_n_llhttp__internal__n_url_to_http_09: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_url_skip_to_http09;
+        return s_n_llhttp__internal__n_url_to_http_09;
+      }
+      switch (*p) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        case 12: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_update_http_major;
+        }
       }
-      p++;
-      goto s_n_llhttp__internal__n_invoke_update_http_major;
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_url_skip_lf_to_http09:
-    s_n_llhttp__internal__n_url_skip_lf_to_http09: {
-      llparse_match_t match_seq;
-      
+    case s_n_llhttp__internal__n_url_skip_to_http09:
+    s_n_llhttp__internal__n_url_skip_to_http09: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_url_skip_lf_to_http09;
+        return s_n_llhttp__internal__n_url_skip_to_http09;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob15, 2);
-      p = match_seq.current;
-      switch (match_seq.status) {
-        case kMatchComplete: {
+      switch (*p) {
+        case 9: {
           p++;
-          goto s_n_llhttp__internal__n_invoke_update_http_major;
+          goto s_n_llhttp__internal__n_error_1;
         }
-        case kMatchPause: {
-          return s_n_llhttp__internal__n_url_skip_lf_to_http09;
+        case 12: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
         }
-        case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_21;
+        default: {
+          p++;
+          goto s_n_llhttp__internal__n_url_to_http_09;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_req_http_end_1:
-    s_n_llhttp__internal__n_req_http_end_1: {
+    case s_n_llhttp__internal__n_url_skip_lf_to_http09_1:
+    s_n_llhttp__internal__n_url_skip_lf_to_http09_1: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_req_http_end_1;
+        return s_n_llhttp__internal__n_url_skip_lf_to_http09_1;
       }
       switch (*p) {
         case 10: {
           p++;
-          goto s_n_llhttp__internal__n_header_field_start;
+          goto s_n_llhttp__internal__n_url_to_http_09;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_22;
+          goto s_n_llhttp__internal__n_error_26;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_req_http_end:
-    s_n_llhttp__internal__n_req_http_end: {
+    case s_n_llhttp__internal__n_url_skip_lf_to_http09:
+    s_n_llhttp__internal__n_url_skip_lf_to_http09: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_req_http_end;
+        return s_n_llhttp__internal__n_url_skip_lf_to_http09;
       }
       switch (*p) {
-        case 10: {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        case 12: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        case 13: {
+          p++;
+          goto s_n_llhttp__internal__n_url_skip_lf_to_http09_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_26;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_pri_upgrade:
+    s_n_llhttp__internal__n_req_pri_upgrade: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_pri_upgrade;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob15, 10);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_error_29;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_req_pri_upgrade;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_30;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_complete_1:
+    s_n_llhttp__internal__n_req_http_complete_1: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_complete_1;
+      }
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_start;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_28;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_complete:
+    s_n_llhttp__internal__n_req_http_complete: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_complete;
+      }
+      switch (*p) {
+        case 10: {
           p++;
           goto s_n_llhttp__internal__n_header_field_start;
         }
         case 13: {
           p++;
-          goto s_n_llhttp__internal__n_req_http_end_1;
+          goto s_n_llhttp__internal__n_req_http_complete_1;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_22;
+          goto s_n_llhttp__internal__n_error_28;
         }
       }
       /* UNREACHABLE */;
@@ -2470,7 +2707,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_http_minor;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_23;
+          goto s_n_llhttp__internal__n_error_31;
         }
       }
       /* UNREACHABLE */;
@@ -2487,7 +2724,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_req_http_minor;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_24;
+          goto s_n_llhttp__internal__n_error_32;
         }
       }
       /* UNREACHABLE */;
@@ -2550,7 +2787,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_http_major;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_25;
+          goto s_n_llhttp__internal__n_error_33;
         }
       }
       /* UNREACHABLE */;
@@ -2563,18 +2800,18 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_req_http_start_1;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob16, 4);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob14, 4);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          goto s_n_llhttp__internal__n_req_http_major;
+          goto s_n_llhttp__internal__n_invoke_load_method;
         }
         case kMatchPause: {
           return s_n_llhttp__internal__n_req_http_start_1;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_27;
+          goto s_n_llhttp__internal__n_error_36;
         }
       }
       /* UNREACHABLE */;
@@ -2587,18 +2824,42 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_req_http_start_2;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob17, 3);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob16, 3);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          goto s_n_llhttp__internal__n_invoke_is_equal_method_1;
+          goto s_n_llhttp__internal__n_invoke_load_method_2;
         }
         case kMatchPause: {
           return s_n_llhttp__internal__n_req_http_start_2;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_27;
+          goto s_n_llhttp__internal__n_error_36;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_start_3:
+    s_n_llhttp__internal__n_req_http_start_3: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_start_3;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob17, 4);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_load_method_3;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_req_http_start_3;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_36;
         }
       }
       /* UNREACHABLE */;
@@ -2622,8 +2883,33 @@ static llparse_state_t llhttp__internal__run(
           p++;
           goto s_n_llhttp__internal__n_req_http_start_2;
         }
+        case 'R': {
+          p++;
+          goto s_n_llhttp__internal__n_req_http_start_3;
+        }
         default: {
-          goto s_n_llhttp__internal__n_error_27;
+          goto s_n_llhttp__internal__n_error_36;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_to_http:
+    s_n_llhttp__internal__n_url_to_http: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_to_http;
+      }
+      switch (*p) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        case 12: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_llhttp__on_url_complete_1;
         }
       }
       /* UNREACHABLE */;
@@ -2634,8 +2920,20 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_url_skip_to_http;
       }
-      p++;
-      goto s_n_llhttp__internal__n_req_http_start;
+      switch (*p) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        case 12: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        default: {
+          p++;
+          goto s_n_llhttp__internal__n_url_to_http;
+        }
+      }
       /* UNREACHABLE */;
       abort();
     }
@@ -2644,20 +2942,20 @@ static llparse_state_t llhttp__internal__run(
       static uint8_t lookup_table[] = {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
       };
       if (p == endp) {
         return s_n_llhttp__internal__n_url_fragment;
@@ -2665,7 +2963,7 @@ static llparse_state_t llhttp__internal__run(
       switch (lookup_table[(uint8_t) *p]) {
         case 1: {
           p++;
-          goto s_n_llhttp__internal__n_url_fragment;
+          goto s_n_llhttp__internal__n_error_1;
         }
         case 2: {
           goto s_n_llhttp__internal__n_span_end_llhttp__on_url_6;
@@ -2676,8 +2974,12 @@ static llparse_state_t llhttp__internal__run(
         case 4: {
           goto s_n_llhttp__internal__n_span_end_llhttp__on_url_8;
         }
+        case 5: {
+          p++;
+          goto s_n_llhttp__internal__n_url_fragment;
+        }
         default: {
-          goto s_n_llhttp__internal__n_error_28;
+          goto s_n_llhttp__internal__n_error_37;
         }
       }
       /* UNREACHABLE */;
@@ -2698,20 +3000,20 @@ static llparse_state_t llhttp__internal__run(
       static uint8_t lookup_table[] = {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        4, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        4, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
       };
       if (p == endp) {
         return s_n_llhttp__internal__n_url_query;
@@ -2719,7 +3021,7 @@ static llparse_state_t llhttp__internal__run(
       switch (lookup_table[(uint8_t) *p]) {
         case 1: {
           p++;
-          goto s_n_llhttp__internal__n_url_query;
+          goto s_n_llhttp__internal__n_error_1;
         }
         case 2: {
           goto s_n_llhttp__internal__n_span_end_llhttp__on_url_9;
@@ -2731,10 +3033,14 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_span_end_llhttp__on_url_11;
         }
         case 5: {
+          p++;
+          goto s_n_llhttp__internal__n_url_query;
+        }
+        case 6: {
           goto s_n_llhttp__internal__n_span_end_stub_query_3;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_29;
+          goto s_n_llhttp__internal__n_error_38;
         }
       }
       /* UNREACHABLE */;
@@ -2746,9 +3052,17 @@ static llparse_state_t llhttp__internal__run(
         return s_n_llhttp__internal__n_url_query_or_fragment;
       }
       switch (*p) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
         case 10: {
           goto s_n_llhttp__internal__n_span_end_llhttp__on_url_3;
         }
+        case 12: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
         case 13: {
           goto s_n_llhttp__internal__n_span_end_llhttp__on_url_4;
         }
@@ -2764,7 +3078,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_url_query;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_30;
+          goto s_n_llhttp__internal__n_error_39;
         }
       }
       /* UNREACHABLE */;
@@ -2775,51 +3089,31 @@ static llparse_state_t llhttp__internal__run(
       static uint8_t lookup_table[] = {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+        0, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
       };
       if (p == endp) {
         return s_n_llhttp__internal__n_url_path;
       }
-      #ifdef __SSE4_2__
-      if (endp - p >= 16) {
-        __m128i ranges;
-        __m128i input;
-        int avail;
-        int match_len;
-      
-        /* Load input */
-        input = _mm_loadu_si128((__m128i const*) p);
-        ranges = _mm_loadu_si128((__m128i const*) llparse_blob1);
-      
-        /* Find first character that does not match `ranges` */
-        match_len = _mm_cmpestri(ranges, 12,
-            input, 16,
-            _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
-              _SIDD_NEGATIVE_POLARITY);
-      
-        if (match_len != 0) {
-          p += match_len;
-          goto s_n_llhttp__internal__n_url_path;
-        }
-        goto s_n_llhttp__internal__n_url_query_or_fragment;
-      }
-      #endif  /* __SSE4_2__ */
       switch (lookup_table[(uint8_t) *p]) {
         case 1: {
           p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        case 2: {
+          p++;
           goto s_n_llhttp__internal__n_url_path;
         }
         default: {
@@ -2862,14 +3156,14 @@ static llparse_state_t llhttp__internal__run(
     case s_n_llhttp__internal__n_url_server_with_at:
     s_n_llhttp__internal__n_url_server_with_at: {
       static uint8_t lookup_table[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        3, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 6,
-        7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 4,
-        0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0,
+        4, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 7,
+        8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5,
+        0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -2884,31 +3178,35 @@ static llparse_state_t llhttp__internal__run(
       }
       switch (lookup_table[(uint8_t) *p]) {
         case 1: {
-          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_12;
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
         }
         case 2: {
-          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_13;
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_12;
         }
         case 3: {
-          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_14;
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_13;
         }
         case 4: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_14;
+        }
+        case 5: {
           p++;
           goto s_n_llhttp__internal__n_url_server;
         }
-        case 5: {
+        case 6: {
           goto s_n_llhttp__internal__n_span_start_stub_path_1;
         }
-        case 6: {
+        case 7: {
           p++;
           goto s_n_llhttp__internal__n_url_query;
         }
-        case 7: {
+        case 8: {
           p++;
-          goto s_n_llhttp__internal__n_error_31;
+          goto s_n_llhttp__internal__n_error_40;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_32;
+          goto s_n_llhttp__internal__n_error_41;
         }
       }
       /* UNREACHABLE */;
@@ -2917,14 +3215,14 @@ static llparse_state_t llhttp__internal__run(
     case s_n_llhttp__internal__n_url_server:
     s_n_llhttp__internal__n_url_server: {
       static uint8_t lookup_table[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        3, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 6,
-        7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 4,
-        0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0,
+        4, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 7,
+        8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5,
+        0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -2939,31 +3237,35 @@ static llparse_state_t llhttp__internal__run(
       }
       switch (lookup_table[(uint8_t) *p]) {
         case 1: {
-          goto s_n_llhttp__internal__n_span_end_llhttp__on_url;
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
         }
         case 2: {
-          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_1;
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url;
         }
         case 3: {
-          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_2;
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_1;
         }
         case 4: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_2;
+        }
+        case 5: {
           p++;
           goto s_n_llhttp__internal__n_url_server;
         }
-        case 5: {
+        case 6: {
           goto s_n_llhttp__internal__n_span_start_stub_path;
         }
-        case 6: {
+        case 7: {
           p++;
           goto s_n_llhttp__internal__n_url_query;
         }
-        case 7: {
+        case 8: {
           p++;
           goto s_n_llhttp__internal__n_url_server_with_at;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_33;
+          goto s_n_llhttp__internal__n_error_42;
         }
       }
       /* UNREACHABLE */;
@@ -2980,7 +3282,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_url_server;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_35;
+          goto s_n_llhttp__internal__n_error_44;
         }
       }
       /* UNREACHABLE */;
@@ -2992,24 +3294,32 @@ static llparse_state_t llhttp__internal__run(
         return s_n_llhttp__internal__n_url_schema_delim;
       }
       switch (*p) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
         case 10: {
           p++;
-          goto s_n_llhttp__internal__n_error_34;
+          goto s_n_llhttp__internal__n_error_43;
+        }
+        case 12: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
         }
         case 13: {
           p++;
-          goto s_n_llhttp__internal__n_error_34;
+          goto s_n_llhttp__internal__n_error_43;
         }
         case ' ': {
           p++;
-          goto s_n_llhttp__internal__n_error_34;
+          goto s_n_llhttp__internal__n_error_43;
         }
         case '/': {
           p++;
           goto s_n_llhttp__internal__n_url_schema_delim_1;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_35;
+          goto s_n_llhttp__internal__n_error_44;
         }
       }
       /* UNREACHABLE */;
@@ -3028,14 +3338,14 @@ static llparse_state_t llhttp__internal__run(
     case s_n_llhttp__internal__n_url_schema:
     s_n_llhttp__internal__n_url_schema: {
       static uint8_t lookup_table[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 2, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
-        0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
-        0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+        2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
+        0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
+        0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -3051,17 +3361,21 @@ static llparse_state_t llhttp__internal__run(
       switch (lookup_table[(uint8_t) *p]) {
         case 1: {
           p++;
-          goto s_n_llhttp__internal__n_error_34;
+          goto s_n_llhttp__internal__n_error_1;
         }
         case 2: {
-          goto s_n_llhttp__internal__n_span_end_stub_schema;
+          p++;
+          goto s_n_llhttp__internal__n_error_43;
         }
         case 3: {
+          goto s_n_llhttp__internal__n_span_end_stub_schema;
+        }
+        case 4: {
           p++;
           goto s_n_llhttp__internal__n_url_schema;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_36;
+          goto s_n_llhttp__internal__n_error_45;
         }
       }
       /* UNREACHABLE */;
@@ -3070,14 +3384,14 @@ static llparse_state_t llhttp__internal__run(
     case s_n_llhttp__internal__n_url_start:
     s_n_llhttp__internal__n_url_start: {
       static uint8_t lookup_table[] = {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 2, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2,
+        2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
-        0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+        0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
+        0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -3093,16 +3407,20 @@ static llparse_state_t llhttp__internal__run(
       switch (lookup_table[(uint8_t) *p]) {
         case 1: {
           p++;
-          goto s_n_llhttp__internal__n_error_34;
+          goto s_n_llhttp__internal__n_error_1;
         }
         case 2: {
-          goto s_n_llhttp__internal__n_span_start_stub_path_2;
+          p++;
+          goto s_n_llhttp__internal__n_error_43;
         }
         case 3: {
+          goto s_n_llhttp__internal__n_span_start_stub_path_2;
+        }
+        case 4: {
           goto s_n_llhttp__internal__n_url_schema;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_37;
+          goto s_n_llhttp__internal__n_error_46;
         }
       }
       /* UNREACHABLE */;
@@ -3119,6 +3437,27 @@ static llparse_state_t llhttp__internal__run(
       /* UNREACHABLE */;
       abort();
     }
+    case s_n_llhttp__internal__n_url_entry_normal:
+    s_n_llhttp__internal__n_url_entry_normal: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_entry_normal;
+      }
+      switch (*p) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        case 12: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_span_start_llhttp__on_url_1;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
     case s_n_llhttp__internal__n_span_start_llhttp__on_url:
     s_n_llhttp__internal__n_span_start_llhttp__on_url: {
       if (p == endp) {
@@ -3130,6 +3469,27 @@ static llparse_state_t llhttp__internal__run(
       /* UNREACHABLE */;
       abort();
     }
+    case s_n_llhttp__internal__n_url_entry_connect:
+    s_n_llhttp__internal__n_url_entry_connect: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_entry_connect;
+      }
+      switch (*p) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        case 12: {
+          p++;
+          goto s_n_llhttp__internal__n_error_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_span_start_llhttp__on_url;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
     case s_n_llhttp__internal__n_req_spaces_before_url:
     s_n_llhttp__internal__n_req_spaces_before_url: {
       if (p == endp) {
@@ -3158,45 +3518,84 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_req_spaces_before_url;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_38;
+          goto s_n_llhttp__internal__n_error_47;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_1:
-    s_n_llhttp__internal__n_start_req_1: {
+    case s_n_llhttp__internal__n_start_req_2:
+    s_n_llhttp__internal__n_start_req_2: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_2;
+      }
+      switch (*p) {
+        case 'L': {
+          p++;
+          match = 19;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_3:
+    s_n_llhttp__internal__n_start_req_3: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_1;
+        return s_n_llhttp__internal__n_start_req_3;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob0, 2);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob18, 6);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 19;
+          match = 36;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_1;
+          return s_n_llhttp__internal__n_start_req_3;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_2:
-    s_n_llhttp__internal__n_start_req_2: {
+    case s_n_llhttp__internal__n_start_req_1:
+    s_n_llhttp__internal__n_start_req_1: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_1;
+      }
+      switch (*p) {
+        case 'C': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_2;
+        }
+        case 'N': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_3;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_4:
+    s_n_llhttp__internal__n_start_req_4: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_2;
+        return s_n_llhttp__internal__n_start_req_4;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob18, 3);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob19, 3);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -3205,23 +3604,23 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_2;
+          return s_n_llhttp__internal__n_start_req_4;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_4:
-    s_n_llhttp__internal__n_start_req_4: {
+    case s_n_llhttp__internal__n_start_req_6:
+    s_n_llhttp__internal__n_start_req_6: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_4;
+        return s_n_llhttp__internal__n_start_req_6;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob19, 6);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob20, 6);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -3230,23 +3629,23 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_4;
+          return s_n_llhttp__internal__n_start_req_6;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_6:
-    s_n_llhttp__internal__n_start_req_6: {
+    case s_n_llhttp__internal__n_start_req_8:
+    s_n_llhttp__internal__n_start_req_8: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_6;
+        return s_n_llhttp__internal__n_start_req_8;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob20, 4);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob21, 4);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -3255,19 +3654,19 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_6;
+          return s_n_llhttp__internal__n_start_req_8;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_7:
-    s_n_llhttp__internal__n_start_req_7: {
+    case s_n_llhttp__internal__n_start_req_9:
+    s_n_llhttp__internal__n_start_req_9: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_7;
+        return s_n_llhttp__internal__n_start_req_9;
       }
       switch (*p) {
         case 'Y': {
@@ -3276,62 +3675,62 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_5:
-    s_n_llhttp__internal__n_start_req_5: {
+    case s_n_llhttp__internal__n_start_req_7:
+    s_n_llhttp__internal__n_start_req_7: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_5;
+        return s_n_llhttp__internal__n_start_req_7;
       }
       switch (*p) {
         case 'N': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_6;
+          goto s_n_llhttp__internal__n_start_req_8;
         }
         case 'P': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_7;
+          goto s_n_llhttp__internal__n_start_req_9;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_3:
-    s_n_llhttp__internal__n_start_req_3: {
+    case s_n_llhttp__internal__n_start_req_5:
+    s_n_llhttp__internal__n_start_req_5: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_3;
+        return s_n_llhttp__internal__n_start_req_5;
       }
       switch (*p) {
         case 'H': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_4;
+          goto s_n_llhttp__internal__n_start_req_6;
         }
         case 'O': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_5;
+          goto s_n_llhttp__internal__n_start_req_7;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_8:
-    s_n_llhttp__internal__n_start_req_8: {
+    case s_n_llhttp__internal__n_start_req_12:
+    s_n_llhttp__internal__n_start_req_12: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_8;
+        return s_n_llhttp__internal__n_start_req_12;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob21, 5);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob22, 3);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -3340,156 +3739,123 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_8;
+          return s_n_llhttp__internal__n_start_req_12;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_9:
-    s_n_llhttp__internal__n_start_req_9: {
+    case s_n_llhttp__internal__n_start_req_13:
+    s_n_llhttp__internal__n_start_req_13: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_9;
+        return s_n_llhttp__internal__n_start_req_13;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob22, 2);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob23, 5);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 1;
+          match = 35;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_9;
+          return s_n_llhttp__internal__n_start_req_13;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_10:
-    s_n_llhttp__internal__n_start_req_10: {
-      llparse_match_t match_seq;
-      
+    case s_n_llhttp__internal__n_start_req_11:
+    s_n_llhttp__internal__n_start_req_11: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_10;
+        return s_n_llhttp__internal__n_start_req_11;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob23, 3);
-      p = match_seq.current;
-      switch (match_seq.status) {
-        case kMatchComplete: {
+      switch (*p) {
+        case 'L': {
           p++;
-          match = 2;
-          goto s_n_llhttp__internal__n_invoke_store_method_1;
+          goto s_n_llhttp__internal__n_start_req_12;
         }
-        case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_10;
+        case 'S': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_13;
         }
-        case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_12:
-    s_n_llhttp__internal__n_start_req_12: {
-      llparse_match_t match_seq;
-      
+    case s_n_llhttp__internal__n_start_req_10:
+    s_n_llhttp__internal__n_start_req_10: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_12;
+        return s_n_llhttp__internal__n_start_req_10;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob24, 2);
-      p = match_seq.current;
-      switch (match_seq.status) {
-        case kMatchComplete: {
+      switch (*p) {
+        case 'E': {
           p++;
-          match = 31;
-          goto s_n_llhttp__internal__n_invoke_store_method_1;
-        }
-        case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_12;
+          goto s_n_llhttp__internal__n_start_req_11;
         }
-        case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_13:
-    s_n_llhttp__internal__n_start_req_13: {
+    case s_n_llhttp__internal__n_start_req_14:
+    s_n_llhttp__internal__n_start_req_14: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_13;
+        return s_n_llhttp__internal__n_start_req_14;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob25, 2);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob24, 4);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 9;
+          match = 45;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_13;
+          return s_n_llhttp__internal__n_start_req_14;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
-        }
-      }
-      /* UNREACHABLE */;
-      abort();
-    }
-    case s_n_llhttp__internal__n_start_req_11:
-    s_n_llhttp__internal__n_start_req_11: {
-      if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_11;
-      }
-      switch (*p) {
-        case 'I': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_12;
-        }
-        case 'O': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_13;
-        }
-        default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_15:
-    s_n_llhttp__internal__n_start_req_15: {
+    case s_n_llhttp__internal__n_start_req_17:
+    s_n_llhttp__internal__n_start_req_17: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_15;
+        return s_n_llhttp__internal__n_start_req_17;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob26, 6);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob26, 9);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 24;
+          match = 41;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_15;
+          return s_n_llhttp__internal__n_start_req_17;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
@@ -3497,24 +3863,41 @@ static llparse_state_t llhttp__internal__run(
     }
     case s_n_llhttp__internal__n_start_req_16:
     s_n_llhttp__internal__n_start_req_16: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_16;
+      }
+      switch (*p) {
+        case '_': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_17;
+        }
+        default: {
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_15:
+    s_n_llhttp__internal__n_start_req_15: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_16;
+        return s_n_llhttp__internal__n_start_req_15;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob27, 3);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob25, 2);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 23;
-          goto s_n_llhttp__internal__n_invoke_store_method_1;
+          goto s_n_llhttp__internal__n_start_req_16;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_16;
+          return s_n_llhttp__internal__n_start_req_15;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
@@ -3527,19 +3910,19 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_start_req_18;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob28, 7);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob27, 3);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 21;
+          match = 2;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
           return s_n_llhttp__internal__n_start_req_18;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
@@ -3552,19 +3935,19 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_start_req_20;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob29, 6);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob28, 2);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 30;
+          match = 31;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
           return s_n_llhttp__internal__n_start_req_20;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
@@ -3572,113 +3955,45 @@ static llparse_state_t llhttp__internal__run(
     }
     case s_n_llhttp__internal__n_start_req_21:
     s_n_llhttp__internal__n_start_req_21: {
-      if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_21;
-      }
-      switch (*p) {
-        case 'L': {
-          p++;
-          match = 10;
-          goto s_n_llhttp__internal__n_invoke_store_method_1;
-        }
-        default: {
-          goto s_n_llhttp__internal__n_error_46;
-        }
-      }
-      /* UNREACHABLE */;
-      abort();
-    }
-    case s_n_llhttp__internal__n_start_req_19:
-    s_n_llhttp__internal__n_start_req_19: {
-      if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_19;
-      }
-      switch (*p) {
-        case 'A': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_20;
-        }
-        case 'O': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_21;
-        }
-        default: {
-          goto s_n_llhttp__internal__n_error_46;
-        }
-      }
-      /* UNREACHABLE */;
-      abort();
-    }
-    case s_n_llhttp__internal__n_start_req_17:
-    s_n_llhttp__internal__n_start_req_17: {
-      if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_17;
-      }
-      switch (*p) {
-        case 'A': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_18;
-        }
-        case 'C': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_19;
-        }
-        default: {
-          goto s_n_llhttp__internal__n_error_46;
-        }
-      }
-      /* UNREACHABLE */;
-      abort();
-    }
-    case s_n_llhttp__internal__n_start_req_22:
-    s_n_llhttp__internal__n_start_req_22: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_22;
+        return s_n_llhttp__internal__n_start_req_21;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob30, 2);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob29, 2);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 11;
+          match = 9;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_22;
+          return s_n_llhttp__internal__n_start_req_21;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_14:
-    s_n_llhttp__internal__n_start_req_14: {
+    case s_n_llhttp__internal__n_start_req_19:
+    s_n_llhttp__internal__n_start_req_19: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_14;
+        return s_n_llhttp__internal__n_start_req_19;
       }
       switch (*p) {
-        case '-': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_15;
-        }
-        case 'E': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_16;
-        }
-        case 'K': {
+        case 'I': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_17;
+          goto s_n_llhttp__internal__n_start_req_20;
         }
         case 'O': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_22;
+          goto s_n_llhttp__internal__n_start_req_21;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
@@ -3691,19 +4006,19 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_start_req_23;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob31, 5);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob30, 6);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 25;
+          match = 24;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
           return s_n_llhttp__internal__n_start_req_23;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
@@ -3716,19 +4031,19 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_start_req_24;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob32, 6);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob31, 3);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 6;
+          match = 23;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
           return s_n_llhttp__internal__n_start_req_24;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
@@ -3741,164 +4056,183 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_start_req_26;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob33, 3);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob32, 7);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 28;
+          match = 21;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
           return s_n_llhttp__internal__n_start_req_26;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_27:
-    s_n_llhttp__internal__n_start_req_27: {
+    case s_n_llhttp__internal__n_start_req_28:
+    s_n_llhttp__internal__n_start_req_28: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_27;
+        return s_n_llhttp__internal__n_start_req_28;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob34, 2);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob33, 6);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 3;
+          match = 30;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_27;
+          return s_n_llhttp__internal__n_start_req_28;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_30:
-    s_n_llhttp__internal__n_start_req_30: {
-      llparse_match_t match_seq;
-      
+    case s_n_llhttp__internal__n_start_req_29:
+    s_n_llhttp__internal__n_start_req_29: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_30;
+        return s_n_llhttp__internal__n_start_req_29;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob36, 3);
-      p = match_seq.current;
-      switch (match_seq.status) {
-        case kMatchComplete: {
+      switch (*p) {
+        case 'L': {
           p++;
-          match = 12;
+          match = 10;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
-        case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_30;
-        }
-        case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_31:
-    s_n_llhttp__internal__n_start_req_31: {
-      llparse_match_t match_seq;
-      
+    case s_n_llhttp__internal__n_start_req_27:
+    s_n_llhttp__internal__n_start_req_27: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_31;
+        return s_n_llhttp__internal__n_start_req_27;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob37, 4);
-      p = match_seq.current;
-      switch (match_seq.status) {
-        case kMatchComplete: {
+      switch (*p) {
+        case 'A': {
           p++;
-          match = 13;
-          goto s_n_llhttp__internal__n_invoke_store_method_1;
+          goto s_n_llhttp__internal__n_start_req_28;
         }
-        case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_31;
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_29;
         }
-        case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_29:
-    s_n_llhttp__internal__n_start_req_29: {
+    case s_n_llhttp__internal__n_start_req_25:
+    s_n_llhttp__internal__n_start_req_25: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_29;
+        return s_n_llhttp__internal__n_start_req_25;
       }
       switch (*p) {
-        case 'F': {
+        case 'A': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_30;
+          goto s_n_llhttp__internal__n_start_req_26;
         }
-        case 'P': {
+        case 'C': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_31;
+          goto s_n_llhttp__internal__n_start_req_27;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_28:
-    s_n_llhttp__internal__n_start_req_28: {
+    case s_n_llhttp__internal__n_start_req_30:
+    s_n_llhttp__internal__n_start_req_30: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_28;
+        return s_n_llhttp__internal__n_start_req_30;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob35, 2);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob34, 2);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          goto s_n_llhttp__internal__n_start_req_29;
+          match = 11;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_28;
+          return s_n_llhttp__internal__n_start_req_30;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_33:
-    s_n_llhttp__internal__n_start_req_33: {
+    case s_n_llhttp__internal__n_start_req_22:
+    s_n_llhttp__internal__n_start_req_22: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_22;
+      }
+      switch (*p) {
+        case '-': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_23;
+        }
+        case 'E': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_24;
+        }
+        case 'K': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_25;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_30;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_31:
+    s_n_llhttp__internal__n_start_req_31: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_33;
+        return s_n_llhttp__internal__n_start_req_31;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob38, 2);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob35, 5);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 29;
+          match = 25;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_33;
+          return s_n_llhttp__internal__n_start_req_31;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_56;
         }
       }
       /* UNREACHABLE */;
@@ -3906,176 +4240,8011 @@ static llparse_state_t llhttp__internal__run(
     }
     case s_n_llhttp__internal__n_start_req_32:
     s_n_llhttp__internal__n_start_req_32: {
+      llparse_match_t match_seq;
+      
       if (p == endp) {
         return s_n_llhttp__internal__n_start_req_32;
       }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob36, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 6;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_32;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_35:
+    s_n_llhttp__internal__n_start_req_35: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_35;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob37, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 28;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_35;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_36:
+    s_n_llhttp__internal__n_start_req_36: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_36;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob38, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 39;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_36;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_34:
+    s_n_llhttp__internal__n_start_req_34: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_34;
+      }
       switch (*p) {
-        case 'R': {
+        case 'T': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_35;
+        }
+        case 'U': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_36;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_37:
+    s_n_llhttp__internal__n_start_req_37: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_37;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob39, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 38;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_37;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_38:
+    s_n_llhttp__internal__n_start_req_38: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_38;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob40, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_38;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_42:
+    s_n_llhttp__internal__n_start_req_42: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_42;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob41, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 12;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_42;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_43:
+    s_n_llhttp__internal__n_start_req_43: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_43;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob42, 4);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 13;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_43;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_41:
+    s_n_llhttp__internal__n_start_req_41: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_41;
+      }
+      switch (*p) {
+        case 'F': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_42;
+        }
+        case 'P': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_43;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_40:
+    s_n_llhttp__internal__n_start_req_40: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_40;
+      }
+      switch (*p) {
+        case 'P': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_41;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_39:
+    s_n_llhttp__internal__n_start_req_39: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_39;
+      }
+      switch (*p) {
+        case 'I': {
+          p++;
+          match = 34;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_40;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_45:
+    s_n_llhttp__internal__n_start_req_45: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_45;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob43, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 29;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_45;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_44:
+    s_n_llhttp__internal__n_start_req_44: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_44;
+      }
+      switch (*p) {
+        case 'R': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_45;
+        }
+        case 'T': {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_33:
+    s_n_llhttp__internal__n_start_req_33: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_33;
+      }
+      switch (*p) {
+        case 'A': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_34;
+        }
+        case 'L': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_37;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_38;
+        }
+        case 'R': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_39;
+        }
+        case 'U': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_44;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_48:
+    s_n_llhttp__internal__n_start_req_48: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_48;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob44, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 17;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_48;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_49:
+    s_n_llhttp__internal__n_start_req_49: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_49;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob45, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 44;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_49;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_50:
+    s_n_llhttp__internal__n_start_req_50: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_50;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob46, 5);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 43;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_50;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_51:
+    s_n_llhttp__internal__n_start_req_51: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_51;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob47, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 20;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_51;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_47:
+    s_n_llhttp__internal__n_start_req_47: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_47;
+      }
+      switch (*p) {
+        case 'B': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_48;
+        }
+        case 'C': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_49;
+        }
+        case 'D': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_50;
+        }
+        case 'P': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_51;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_46:
+    s_n_llhttp__internal__n_start_req_46: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_46;
+      }
+      switch (*p) {
+        case 'E': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_47;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_54:
+    s_n_llhttp__internal__n_start_req_54: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_54;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob48, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 14;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_54;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_56:
+    s_n_llhttp__internal__n_start_req_56: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_56;
+      }
+      switch (*p) {
+        case 'P': {
+          p++;
+          match = 37;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_57:
+    s_n_llhttp__internal__n_start_req_57: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_57;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob49, 9);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 42;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_57;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_55:
+    s_n_llhttp__internal__n_start_req_55: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_55;
+      }
+      switch (*p) {
+        case 'U': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_56;
+        }
+        case '_': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_57;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_53:
+    s_n_llhttp__internal__n_start_req_53: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_53;
+      }
+      switch (*p) {
+        case 'A': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_54;
+        }
+        case 'T': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_55;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_58:
+    s_n_llhttp__internal__n_start_req_58: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_58;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob50, 4);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 33;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_58;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_59:
+    s_n_llhttp__internal__n_start_req_59: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_59;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob51, 7);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 26;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_59;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_52:
+    s_n_llhttp__internal__n_start_req_52: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_52;
+      }
+      switch (*p) {
+        case 'E': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_53;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_58;
+        }
+        case 'U': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_59;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_61:
+    s_n_llhttp__internal__n_start_req_61: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_61;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob52, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 40;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_61;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_62:
+    s_n_llhttp__internal__n_start_req_62: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_62;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob53, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 7;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_62;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_60:
+    s_n_llhttp__internal__n_start_req_60: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_60;
+      }
+      switch (*p) {
+        case 'E': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_61;
+        }
+        case 'R': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_62;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_65:
+    s_n_llhttp__internal__n_start_req_65: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_65;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob54, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 18;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_65;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_67:
+    s_n_llhttp__internal__n_start_req_67: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_67;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob55, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 32;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_67;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_68:
+    s_n_llhttp__internal__n_start_req_68: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_68;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob56, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 15;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_68;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_66:
+    s_n_llhttp__internal__n_start_req_66: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_66;
+      }
+      switch (*p) {
+        case 'I': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_67;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_68;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_69:
+    s_n_llhttp__internal__n_start_req_69: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_69;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob57, 8);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 27;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_69;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_64:
+    s_n_llhttp__internal__n_start_req_64: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_64;
+      }
+      switch (*p) {
+        case 'B': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_65;
+        }
+        case 'L': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_66;
+        }
+        case 'S': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_69;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_63:
+    s_n_llhttp__internal__n_start_req_63: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_63;
+      }
+      switch (*p) {
+        case 'N': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_64;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req:
+    s_n_llhttp__internal__n_start_req: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req;
+      }
+      switch (*p) {
+        case 'A': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_1;
+        }
+        case 'B': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_4;
+        }
+        case 'C': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_5;
+        }
+        case 'D': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_10;
+        }
+        case 'F': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_14;
+        }
+        case 'G': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_15;
+        }
+        case 'H': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_18;
+        }
+        case 'L': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_19;
+        }
+        case 'M': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_22;
+        }
+        case 'N': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_31;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_32;
+        }
+        case 'P': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_33;
+        }
+        case 'R': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_46;
+        }
+        case 'S': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_52;
+        }
+        case 'T': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_60;
+        }
+        case 'U': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_63;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_56;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_llhttp__on_status_complete:
+    s_n_llhttp__internal__n_invoke_llhttp__on_status_complete: {
+      switch (llhttp__on_status_complete(state, p, endp)) {
+        default:
+          goto s_n_llhttp__internal__n_header_field_start;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_res_line_almost_done:
+    s_n_llhttp__internal__n_res_line_almost_done: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_res_line_almost_done;
+      }
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_res_status:
+    s_n_llhttp__internal__n_res_status: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_res_status;
+      }
+      switch (*p) {
+        case 10: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_status;
+        }
+        case 13: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_status_1;
+        }
+        default: {
+          p++;
+          goto s_n_llhttp__internal__n_res_status;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_llhttp__on_status:
+    s_n_llhttp__internal__n_span_start_llhttp__on_status: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_llhttp__on_status;
+      }
+      state->_span_pos0 = (void*) p;
+      state->_span_cb0 = llhttp__on_status;
+      goto s_n_llhttp__internal__n_res_status;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_res_status_start:
+    s_n_llhttp__internal__n_res_status_start: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_res_status_start;
+      }
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete;
+        }
+        case 13: {
+          p++;
+          goto s_n_llhttp__internal__n_res_line_almost_done;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_span_start_llhttp__on_status;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_res_status_code_otherwise:
+    s_n_llhttp__internal__n_res_status_code_otherwise: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_res_status_code_otherwise;
+      }
+      switch (*p) {
+        case 10: {
+          goto s_n_llhttp__internal__n_res_status_start;
+        }
+        case 13: {
+          goto s_n_llhttp__internal__n_res_status_start;
+        }
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_res_status_start;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_50;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_res_status_code:
+    s_n_llhttp__internal__n_res_status_code: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_res_status_code;
+      }
+      switch (*p) {
+        case '0': {
+          p++;
+          match = 0;
+          goto s_n_llhttp__internal__n_invoke_mul_add_status_code;
+        }
+        case '1': {
+          p++;
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_mul_add_status_code;
+        }
+        case '2': {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_mul_add_status_code;
+        }
+        case '3': {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_mul_add_status_code;
+        }
+        case '4': {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_mul_add_status_code;
+        }
+        case '5': {
+          p++;
+          match = 5;
+          goto s_n_llhttp__internal__n_invoke_mul_add_status_code;
+        }
+        case '6': {
+          p++;
+          match = 6;
+          goto s_n_llhttp__internal__n_invoke_mul_add_status_code;
+        }
+        case '7': {
+          p++;
+          match = 7;
+          goto s_n_llhttp__internal__n_invoke_mul_add_status_code;
+        }
+        case '8': {
+          p++;
+          match = 8;
+          goto s_n_llhttp__internal__n_invoke_mul_add_status_code;
+        }
+        case '9': {
+          p++;
+          match = 9;
+          goto s_n_llhttp__internal__n_invoke_mul_add_status_code;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_res_status_code_otherwise;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_res_http_end:
+    s_n_llhttp__internal__n_res_http_end: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_res_http_end;
+      }
+      switch (*p) {
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_update_status_code;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_51;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_res_http_minor:
+    s_n_llhttp__internal__n_res_http_minor: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_res_http_minor;
+      }
+      switch (*p) {
+        case '0': {
+          p++;
+          match = 0;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
+        }
+        case '1': {
+          p++;
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
+        }
+        case '2': {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
+        }
+        case '3': {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
+        }
+        case '4': {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
+        }
+        case '5': {
+          p++;
+          match = 5;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
+        }
+        case '6': {
+          p++;
+          match = 6;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
+        }
+        case '7': {
+          p++;
+          match = 7;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
+        }
+        case '8': {
+          p++;
+          match = 8;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
+        }
+        case '9': {
+          p++;
+          match = 9;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_52;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_res_http_dot:
+    s_n_llhttp__internal__n_res_http_dot: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_res_http_dot;
+      }
+      switch (*p) {
+        case '.': {
+          p++;
+          goto s_n_llhttp__internal__n_res_http_minor;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_53;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_res_http_major:
+    s_n_llhttp__internal__n_res_http_major: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_res_http_major;
+      }
+      switch (*p) {
+        case '0': {
+          p++;
+          match = 0;
+          goto s_n_llhttp__internal__n_invoke_store_http_major_1;
+        }
+        case '1': {
+          p++;
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_store_http_major_1;
+        }
+        case '2': {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_store_http_major_1;
+        }
+        case '3': {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_store_http_major_1;
+        }
+        case '4': {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_store_http_major_1;
+        }
+        case '5': {
+          p++;
+          match = 5;
+          goto s_n_llhttp__internal__n_invoke_store_http_major_1;
+        }
+        case '6': {
+          p++;
+          match = 6;
+          goto s_n_llhttp__internal__n_invoke_store_http_major_1;
+        }
+        case '7': {
+          p++;
+          match = 7;
+          goto s_n_llhttp__internal__n_invoke_store_http_major_1;
+        }
+        case '8': {
+          p++;
+          match = 8;
+          goto s_n_llhttp__internal__n_invoke_store_http_major_1;
+        }
+        case '9': {
+          p++;
+          match = 9;
+          goto s_n_llhttp__internal__n_invoke_store_http_major_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_54;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_res:
+    s_n_llhttp__internal__n_start_res: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_res;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob58, 5);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_res_http_major;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_res;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_57;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_or_res_method_2:
+    s_n_llhttp__internal__n_req_or_res_method_2: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_or_res_method_2;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob59, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_store_method;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_req_or_res_method_2;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_55;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_or_res_method_3:
+    s_n_llhttp__internal__n_req_or_res_method_3: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_or_res_method_3;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob60, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_update_type_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_req_or_res_method_3;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_55;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_or_res_method_1:
+    s_n_llhttp__internal__n_req_or_res_method_1: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_or_res_method_1;
+      }
+      switch (*p) {
+        case 'E': {
+          p++;
+          goto s_n_llhttp__internal__n_req_or_res_method_2;
+        }
+        case 'T': {
+          p++;
+          goto s_n_llhttp__internal__n_req_or_res_method_3;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_55;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_or_res_method:
+    s_n_llhttp__internal__n_req_or_res_method: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_or_res_method;
+      }
+      switch (*p) {
+        case 'H': {
+          p++;
+          goto s_n_llhttp__internal__n_req_or_res_method_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_55;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_or_res:
+    s_n_llhttp__internal__n_start_req_or_res: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_or_res;
+      }
+      switch (*p) {
+        case 'H': {
+          goto s_n_llhttp__internal__n_req_or_res_method;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_update_type_2;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_load_type:
+    s_n_llhttp__internal__n_invoke_load_type: {
+      switch (llhttp__internal__c_load_type(state, p, endp)) {
+        case 1:
+          goto s_n_llhttp__internal__n_start_req;
+        case 2:
+          goto s_n_llhttp__internal__n_start_res;
+        default:
+          goto s_n_llhttp__internal__n_start_req_or_res;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start:
+    s_n_llhttp__internal__n_start: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start;
+      }
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_start;
+        }
+        case 13: {
+          p++;
+          goto s_n_llhttp__internal__n_start;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_update_finish;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    default:
+      /* UNREACHABLE */
+      abort();
+  }
+  s_n_llhttp__internal__n_error_1: {
+    state->error = 0x7;
+    state->reason = "Invalid characters in url (strict mode)";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_43: {
+    state->error = 0x7;
+    state->reason = "Invalid characters in url";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_finish_2: {
+    switch (llhttp__internal__c_update_finish_1(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_start;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_4: {
+    state->error = 0x5;
+    state->reason = "Data after `Connection: close`";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_test_lenient_flags: {
+    switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) {
+      case 1:
+        goto s_n_llhttp__internal__n_invoke_update_finish_2;
+      default:
+        goto s_n_llhttp__internal__n_closed;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_finish_1: {
+    switch (llhttp__internal__c_update_finish_1(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_test_lenient_flags;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_pause_5: {
+    state->error = 0x15;
+    state->reason = "on_message_complete pause";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_is_equal_upgrade;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_13: {
+    state->error = 0x12;
+    state->reason = "`on_message_complete` callback error";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_pause_7: {
+    state->error = 0x15;
+    state->reason = "on_chunk_complete pause";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_16: {
+    state->error = 0x14;
+    state->reason = "`on_chunk_complete` callback error";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete_1: {
+    switch (llhttp__on_chunk_complete(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2;
+      case 21:
+        goto s_n_llhttp__internal__n_pause_7;
+      default:
+        goto s_n_llhttp__internal__n_error_16;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_15: {
+    state->error = 0x4;
+    state->reason = "Content-Length can't be present with Transfer-Encoding";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_pause_2: {
+    state->error = 0x15;
+    state->reason = "on_message_complete pause";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_pause_1;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_5: {
+    state->error = 0x12;
+    state->reason = "`on_message_complete` callback error";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_1: {
+    switch (llhttp__on_message_complete(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_pause_1;
+      case 21:
+        goto s_n_llhttp__internal__n_pause_2;
+      default:
+        goto s_n_llhttp__internal__n_error_5;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_11: {
+    state->error = 0xc;
+    state->reason = "Chunk size overflow";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_pause_3: {
+    state->error = 0x15;
+    state->reason = "on_chunk_complete pause";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_update_content_length;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_7: {
+    state->error = 0x14;
+    state->reason = "`on_chunk_complete` callback error";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete: {
+    switch (llhttp__on_chunk_complete(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_invoke_update_content_length;
+      case 21:
+        goto s_n_llhttp__internal__n_pause_3;
+      default:
+        goto s_n_llhttp__internal__n_error_7;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_8: {
+    state->error = 0x2;
+    state->reason = "Expected CRLF after chunk";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_body: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_body(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_data_almost_done;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_chunk_data_almost_done;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags: {
+    switch (llhttp__internal__c_or_flags(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_field_start;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_pause_4: {
+    state->error = 0x15;
+    state->reason = "on_chunk_header pause";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_is_equal_content_length;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_6: {
+    state->error = 0x13;
+    state->reason = "`on_chunk_header` callback error";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__on_chunk_header: {
+    switch (llhttp__on_chunk_header(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_invoke_is_equal_content_length;
+      case 21:
+        goto s_n_llhttp__internal__n_pause_4;
+      default:
+        goto s_n_llhttp__internal__n_error_6;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_9: {
+    state->error = 0x2;
+    state->reason = "Expected LF after chunk size";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_10: {
+    state->error = 0xc;
+    state->reason = "Invalid character in chunk size";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_mul_add_content_length: {
+    switch (llhttp__internal__c_mul_add_content_length(state, p, endp, match)) {
+      case 1:
+        goto s_n_llhttp__internal__n_error_11;
+      default:
+        goto s_n_llhttp__internal__n_chunk_size;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_12: {
+    state->error = 0xc;
+    state->reason = "Invalid character in chunk size";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_body_1: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_body(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_finish_3: {
+    switch (llhttp__internal__c_update_finish_3(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_span_start_llhttp__on_body_2;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_14: {
+    state->error = 0xf;
+    state->reason = "Request has invalid `Transfer-Encoding`";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_pause: {
+    state->error = 0x15;
+    state->reason = "on_message_complete pause";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_message_complete;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_3: {
+    state->error = 0x12;
+    state->reason = "`on_message_complete` callback error";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__on_message_complete: {
+    switch (llhttp__on_message_complete(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_invoke_llhttp__after_message_complete;
+      case 21:
+        goto s_n_llhttp__internal__n_pause;
+      default:
+        goto s_n_llhttp__internal__n_error_3;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_1: {
+    switch (llhttp__internal__c_or_flags_1(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_2: {
+    switch (llhttp__internal__c_or_flags_1(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_upgrade: {
+    switch (llhttp__internal__c_update_upgrade(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_or_flags_2;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_pause_6: {
+    state->error = 0x15;
+    state->reason = "Paused by on_headers_complete";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_2: {
+    state->error = 0x11;
+    state->reason = "User callback error";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__on_headers_complete: {
+    switch (llhttp__on_headers_complete(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete;
+      case 1:
+        goto s_n_llhttp__internal__n_invoke_or_flags_1;
+      case 2:
+        goto s_n_llhttp__internal__n_invoke_update_upgrade;
+      case 21:
+        goto s_n_llhttp__internal__n_pause_6;
+      default:
+        goto s_n_llhttp__internal__n_error_2;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete: {
+    switch (llhttp__before_headers_complete(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_headers_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_test_lenient_flags_1: {
+    switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_error_15;
+      default:
+        goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_test_flags_1: {
+    switch (llhttp__internal__c_test_flags_1(state, p, endp)) {
+      case 1:
+        goto s_n_llhttp__internal__n_invoke_test_lenient_flags_1;
+      default:
+        goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_test_flags: {
+    switch (llhttp__internal__c_test_flags(state, p, endp)) {
+      case 1:
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete_1;
+      default:
+        goto s_n_llhttp__internal__n_invoke_test_flags_1;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_17: {
+    state->error = 0x2;
+    state->reason = "Expected LF after headers";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_18: {
+    state->error = 0xb;
+    state->reason = "Empty Content-Length";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_header_value: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_header_value(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state: {
+    switch (llhttp__internal__c_update_header_state(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_3: {
+    switch (llhttp__internal__c_or_flags_3(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_header_state;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_4: {
+    switch (llhttp__internal__c_or_flags_4(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_header_state;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_5: {
+    switch (llhttp__internal__c_or_flags_5(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_header_state;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_6: {
+    switch (llhttp__internal__c_or_flags_6(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_header_state_1: {
+    switch (llhttp__internal__c_load_header_state(state, p, endp)) {
+      case 5:
+        goto s_n_llhttp__internal__n_invoke_or_flags_3;
+      case 6:
+        goto s_n_llhttp__internal__n_invoke_or_flags_4;
+      case 7:
+        goto s_n_llhttp__internal__n_invoke_or_flags_5;
+      case 8:
+        goto s_n_llhttp__internal__n_invoke_or_flags_6;
+      default:
+        goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_header_state: {
+    switch (llhttp__internal__c_load_header_state(state, p, endp)) {
+      case 2:
+        goto s_n_llhttp__internal__n_error_18;
+      default:
+        goto s_n_llhttp__internal__n_invoke_load_header_state_1;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_19: {
+    state->error = 0x2;
+    state->reason = "Expected LF after CR";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state_1: {
+    switch (llhttp__internal__c_update_header_state(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_7: {
+    switch (llhttp__internal__c_or_flags_3(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_header_state_1;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_8: {
+    switch (llhttp__internal__c_or_flags_4(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_header_state_1;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_9: {
+    switch (llhttp__internal__c_or_flags_5(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_header_state_1;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_10: {
+    switch (llhttp__internal__c_or_flags_6(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_header_state_3: {
+    switch (llhttp__internal__c_load_header_state(state, p, endp)) {
+      case 5:
+        goto s_n_llhttp__internal__n_invoke_or_flags_7;
+      case 6:
+        goto s_n_llhttp__internal__n_invoke_or_flags_8;
+      case 7:
+        goto s_n_llhttp__internal__n_invoke_or_flags_9;
+      case 8:
+        goto s_n_llhttp__internal__n_invoke_or_flags_10;
+      default:
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_20: {
+    state->error = 0x3;
+    state->reason = "Missing expected LF after header value";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_header_value_1: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_header_value(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_almost_done;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_header_value_almost_done;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_header_value_2: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_header_value(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) (p + 1);
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_almost_done;
+      return s_error;
+    }
+    p++;
+    goto s_n_llhttp__internal__n_header_value_almost_done;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_header_value_3: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_header_value(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) (p + 1);
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_almost_done;
+      return s_error;
+    }
+    p++;
+    goto s_n_llhttp__internal__n_header_value_almost_done;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_21: {
+    state->error = 0xa;
+    state->reason = "Invalid header value char";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_test_lenient_flags_2: {
+    switch (llhttp__internal__c_test_lenient_flags_2(state, p, endp)) {
+      case 1:
+        goto s_n_llhttp__internal__n_header_value_lenient;
+      default:
+        goto s_n_llhttp__internal__n_error_21;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state_3: {
+    switch (llhttp__internal__c_update_header_state(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value_connection;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_11: {
+    switch (llhttp__internal__c_or_flags_3(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_header_state_3;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_12: {
+    switch (llhttp__internal__c_or_flags_4(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_header_state_3;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_13: {
+    switch (llhttp__internal__c_or_flags_5(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_header_state_3;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_14: {
+    switch (llhttp__internal__c_or_flags_6(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value_connection;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_header_state_4: {
+    switch (llhttp__internal__c_load_header_state(state, p, endp)) {
+      case 5:
+        goto s_n_llhttp__internal__n_invoke_or_flags_11;
+      case 6:
+        goto s_n_llhttp__internal__n_invoke_or_flags_12;
+      case 7:
+        goto s_n_llhttp__internal__n_invoke_or_flags_13;
+      case 8:
+        goto s_n_llhttp__internal__n_invoke_or_flags_14;
+      default:
+        goto s_n_llhttp__internal__n_header_value_connection;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state_4: {
+    switch (llhttp__internal__c_update_header_state_4(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value_connection_token;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state_2: {
+    switch (llhttp__internal__c_update_header_state_2(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value_connection_ws;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state_5: {
+    switch (llhttp__internal__c_update_header_state_5(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value_connection_ws;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state_6: {
+    switch (llhttp__internal__c_update_header_state_6(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value_connection_ws;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_header_value_4: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_header_value(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_23;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_error_23;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_mul_add_content_length_1: {
+    switch (llhttp__internal__c_mul_add_content_length_1(state, p, endp, match)) {
+      case 1:
+        goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_4;
+      default:
+        goto s_n_llhttp__internal__n_header_value_content_length;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_15: {
+    switch (llhttp__internal__c_or_flags_15(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value_otherwise;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_header_value_5: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_header_value(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_24;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_error_24;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_22: {
+    state->error = 0x4;
+    state->reason = "Duplicate Content-Length";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_test_flags_2: {
+    switch (llhttp__internal__c_test_flags_2(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_header_value_content_length;
+      default:
+        goto s_n_llhttp__internal__n_error_22;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state_7: {
+    switch (llhttp__internal__c_update_header_state_7(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value_otherwise;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state_8: {
+    switch (llhttp__internal__c_update_header_state_4(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_and_flags: {
+    switch (llhttp__internal__c_and_flags(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value_te_chunked;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_16: {
+    switch (llhttp__internal__c_or_flags_16(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_and_flags;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_or_flags_17: {
+    switch (llhttp__internal__c_or_flags_17(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_header_state_8;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_header_state_2: {
+    switch (llhttp__internal__c_load_header_state(state, p, endp)) {
+      case 1:
+        goto s_n_llhttp__internal__n_header_value_connection;
+      case 2:
+        goto s_n_llhttp__internal__n_invoke_test_flags_2;
+      case 3:
+        goto s_n_llhttp__internal__n_invoke_or_flags_16;
+      case 4:
+        goto s_n_llhttp__internal__n_invoke_or_flags_17;
+      default:
+        goto s_n_llhttp__internal__n_header_value;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_header_field: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_header_field(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) (p + 1);
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete;
+      return s_error;
+    }
+    p++;
+    goto s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_header_field_1: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_header_field(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) (p + 1);
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete;
+      return s_error;
+    }
+    p++;
+    goto s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_25: {
+    state->error = 0xa;
+    state->reason = "Invalid header token";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state_9: {
+    switch (llhttp__internal__c_update_header_state_4(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_field_general;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_store_header_state: {
+    switch (llhttp__internal__c_store_header_state(state, p, endp, match)) {
+      default:
+        goto s_n_llhttp__internal__n_header_field_colon;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_header_state_10: {
+    switch (llhttp__internal__c_update_header_state_4(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_field_general;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__on_url_complete: {
+    switch (llhttp__on_url_complete(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_field_start;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_http_minor: {
+    switch (llhttp__internal__c_update_http_minor(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_url_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_http_major: {
+    switch (llhttp__internal__c_update_http_major(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_http_minor;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_3: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_to_http09;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_26: {
+    state->error = 0x7;
+    state->reason = "Expected CRLF";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_4: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_lf_to_http09;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_29: {
+    state->error = 0x17;
+    state->reason = "Pause on PRI/Upgrade";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_30: {
+    state->error = 0x9;
+    state->reason = "Expected HTTP/2 Connection Preface";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_28: {
+    state->error = 0x9;
+    state->reason = "Expected CRLF after version";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_method_1: {
+    switch (llhttp__internal__c_load_method(state, p, endp)) {
+      case 34:
+        goto s_n_llhttp__internal__n_req_pri_upgrade;
+      default:
+        goto s_n_llhttp__internal__n_req_http_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_store_http_minor: {
+    switch (llhttp__internal__c_store_http_minor(state, p, endp, match)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_load_method_1;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_31: {
+    state->error = 0x9;
+    state->reason = "Invalid minor version";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_32: {
+    state->error = 0x9;
+    state->reason = "Expected dot";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_store_http_major: {
+    switch (llhttp__internal__c_store_http_major(state, p, endp, match)) {
+      default:
+        goto s_n_llhttp__internal__n_req_http_dot;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_33: {
+    state->error = 0x9;
+    state->reason = "Invalid major version";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_27: {
+    state->error = 0x8;
+    state->reason = "Invalid method for HTTP/x.x request";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_method: {
+    switch (llhttp__internal__c_load_method(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 1:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 2:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 3:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 4:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 5:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 6:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 7:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 8:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 9:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 10:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 11:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 12:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 13:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 14:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 15:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 16:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 17:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 18:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 19:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 20:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 21:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 22:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 23:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 24:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 25:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 26:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 27:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 28:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 29:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 30:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 31:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 32:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 33:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 34:
+        goto s_n_llhttp__internal__n_req_http_major;
+      default:
+        goto s_n_llhttp__internal__n_error_27;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_36: {
+    state->error = 0x8;
+    state->reason = "Expected HTTP/";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_34: {
+    state->error = 0x8;
+    state->reason = "Expected SOURCE method for ICE/x.x request";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_method_2: {
+    switch (llhttp__internal__c_load_method(state, p, endp)) {
+      case 33:
+        goto s_n_llhttp__internal__n_req_http_major;
+      default:
+        goto s_n_llhttp__internal__n_error_34;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_35: {
+    state->error = 0x8;
+    state->reason = "Invalid method for RTSP/x.x request";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_method_3: {
+    switch (llhttp__internal__c_load_method(state, p, endp)) {
+      case 1:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 3:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 6:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 35:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 36:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 37:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 38:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 39:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 40:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 41:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 42:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 43:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 44:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 45:
+        goto s_n_llhttp__internal__n_req_http_major;
+      default:
+        goto s_n_llhttp__internal__n_error_35;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__on_url_complete_1: {
+    switch (llhttp__on_url_complete(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_req_http_start;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_5: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_to_http;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_6: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_to_http09;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_7: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_lf_to_http09;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_8: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_to_http;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_37: {
+    state->error = 0x7;
+    state->reason = "Invalid char in url fragment start";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_9: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_to_http09;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_10: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_lf_to_http09;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_11: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_to_http;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_38: {
+    state->error = 0x7;
+    state->reason = "Invalid char in url query";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_39: {
+    state->error = 0x7;
+    state->reason = "Invalid char in url path";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_to_http09;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_1: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_lf_to_http09;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_2: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_to_http;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_12: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_to_http09;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_13: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_lf_to_http09;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_url_14: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_url(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http;
+      return s_error;
+    }
+    goto s_n_llhttp__internal__n_url_skip_to_http;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_40: {
+    state->error = 0x7;
+    state->reason = "Double @ in url";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_41: {
+    state->error = 0x7;
+    state->reason = "Unexpected char in url server";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_42: {
+    state->error = 0x7;
+    state->reason = "Unexpected char in url server";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_44: {
+    state->error = 0x7;
+    state->reason = "Unexpected char in url schema";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_45: {
+    state->error = 0x7;
+    state->reason = "Unexpected char in url schema";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_46: {
+    state->error = 0x7;
+    state->reason = "Unexpected start char in url";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_is_equal_method: {
+    switch (llhttp__internal__c_is_equal_method(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_url_entry_normal;
+      default:
+        goto s_n_llhttp__internal__n_url_entry_connect;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_47: {
+    state->error = 0x6;
+    state->reason = "Expected space after method";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_store_method_1: {
+    switch (llhttp__internal__c_store_method(state, p, endp, match)) {
+      default:
+        goto s_n_llhttp__internal__n_req_first_space_before_url;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_56: {
+    state->error = 0x6;
+    state->reason = "Invalid method encountered";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_48: {
+    state->error = 0xd;
+    state->reason = "Response overflow";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_mul_add_status_code: {
+    switch (llhttp__internal__c_mul_add_status_code(state, p, endp, match)) {
+      case 1:
+        goto s_n_llhttp__internal__n_error_48;
+      default:
+        goto s_n_llhttp__internal__n_res_status_code;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_49: {
+    state->error = 0x2;
+    state->reason = "Expected LF after CR";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_status: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_status(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) (p + 1);
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_status_complete;
+      return s_error;
+    }
+    p++;
+    goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_span_end_llhttp__on_status_1: {
+    const unsigned char* start;
+    int err;
+    
+    start = state->_span_pos0;
+    state->_span_pos0 = NULL;
+    err = llhttp__on_status(state, start, p);
+    if (err != 0) {
+      state->error = err;
+      state->error_pos = (const char*) (p + 1);
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_res_line_almost_done;
+      return s_error;
+    }
+    p++;
+    goto s_n_llhttp__internal__n_res_line_almost_done;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_50: {
+    state->error = 0xd;
+    state->reason = "Invalid response status";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_status_code: {
+    switch (llhttp__internal__c_update_status_code(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_res_status_code;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_51: {
+    state->error = 0x9;
+    state->reason = "Expected space after version";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_store_http_minor_1: {
+    switch (llhttp__internal__c_store_http_minor(state, p, endp, match)) {
+      default:
+        goto s_n_llhttp__internal__n_res_http_end;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_52: {
+    state->error = 0x9;
+    state->reason = "Invalid minor version";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_53: {
+    state->error = 0x9;
+    state->reason = "Expected dot";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_store_http_major_1: {
+    switch (llhttp__internal__c_store_http_major(state, p, endp, match)) {
+      default:
+        goto s_n_llhttp__internal__n_res_http_dot;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_54: {
+    state->error = 0x9;
+    state->reason = "Invalid major version";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_57: {
+    state->error = 0x8;
+    state->reason = "Expected HTTP/";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_type: {
+    switch (llhttp__internal__c_update_type(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_req_first_space_before_url;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_store_method: {
+    switch (llhttp__internal__c_store_method(state, p, endp, match)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_update_type;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_55: {
+    state->error = 0x8;
+    state->reason = "Invalid word encountered";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_type_1: {
+    switch (llhttp__internal__c_update_type_1(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_res_http_major;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_type_2: {
+    switch (llhttp__internal__c_update_type(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_start_req;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_pause_8: {
+    state->error = 0x15;
+    state->reason = "on_message_begin pause";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_type;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error: {
+    state->error = 0x10;
+    state->reason = "`on_message_begin` callback error";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__on_message_begin: {
+    switch (llhttp__on_message_begin(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_invoke_load_type;
+      case 21:
+        goto s_n_llhttp__internal__n_pause_8;
+      default:
+        goto s_n_llhttp__internal__n_error;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_finish: {
+    switch (llhttp__internal__c_update_finish(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_message_begin;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+}
+
+int llhttp__internal_execute(llhttp__internal_t* state, const char* p, const char* endp) {
+  llparse_state_t next;
+
+  /* check lingering errors */
+  if (state->error != 0) {
+    return state->error;
+  }
+
+  /* restart spans */
+  if (state->_span_pos0 != NULL) {
+    state->_span_pos0 = (void*) p;
+  }
+  
+  next = llhttp__internal__run(state, (const unsigned char*) p, (const unsigned char*) endp);
+  if (next == s_error) {
+    return state->error;
+  }
+  state->_current = (void*) (intptr_t) next;
+
+  /* execute spans */
+  if (state->_span_pos0 != NULL) {
+    int error;
+  
+    error = ((llhttp__internal__span_cb) state->_span_cb0)(state, state->_span_pos0, (const char*) endp);
+    if (error != 0) {
+      state->error = error;
+      state->error_pos = endp;
+      return error;
+    }
+  }
+  
+  return 0;
+}
+
+#else  /* !LLHTTP_STRICT_MODE */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#ifdef __SSE4_2__
+ #ifdef _MSC_VER
+  #include <nmmintrin.h>
+ #else  /* !_MSC_VER */
+  #include <x86intrin.h>
+ #endif  /* _MSC_VER */
+#endif  /* __SSE4_2__ */
+
+#ifdef _MSC_VER
+ #define ALIGN(n) _declspec(align(n))
+#else  /* !_MSC_VER */
+ #define ALIGN(n) __attribute__((aligned(n)))
+#endif  /* _MSC_VER */
+
+#include "llhttp.h"
+
+typedef int (*llhttp__internal__span_cb)(
+             llhttp__internal_t*, const char*, const char*);
+
+#ifdef __SSE4_2__
+static const unsigned char ALIGN(16) llparse_blob0[] = {
+  0x9, 0x9, 0xc, 0xc, '!', '"', '$', '>', '@', '~', 0x80,
+  0xff, 0x0, 0x0, 0x0, 0x0
+};
+#endif  /* __SSE4_2__ */
+static const unsigned char llparse_blob1[] = {
+  'o', 'n'
+};
+static const unsigned char llparse_blob2[] = {
+  'e', 'c', 't', 'i', 'o', 'n'
+};
+static const unsigned char llparse_blob3[] = {
+  'l', 'o', 's', 'e'
+};
+static const unsigned char llparse_blob4[] = {
+  'e', 'e', 'p', '-', 'a', 'l', 'i', 'v', 'e'
+};
+static const unsigned char llparse_blob5[] = {
+  'p', 'g', 'r', 'a', 'd', 'e'
+};
+static const unsigned char llparse_blob6[] = {
+  'c', 'h', 'u', 'n', 'k', 'e', 'd'
+};
+#ifdef __SSE4_2__
+static const unsigned char ALIGN(16) llparse_blob7[] = {
+  0x9, 0x9, ' ', '~', 0x80, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0,
+  0x0, 0x0, 0x0, 0x0, 0x0
+};
+#endif  /* __SSE4_2__ */
+#ifdef __SSE4_2__
+static const unsigned char ALIGN(16) llparse_blob8[] = {
+  ' ', '!', '#', '\'', '*', '+', '-', '.', '0', '9', 'A',
+  'Z', '^', 'z', '|', '|'
+};
+#endif  /* __SSE4_2__ */
+#ifdef __SSE4_2__
+static const unsigned char ALIGN(16) llparse_blob9[] = {
+  '~', '~', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+  0x0, 0x0, 0x0, 0x0, 0x0
+};
+#endif  /* __SSE4_2__ */
+static const unsigned char llparse_blob10[] = {
+  'e', 'n', 't', '-', 'l', 'e', 'n', 'g', 't', 'h'
+};
+static const unsigned char llparse_blob11[] = {
+  'r', 'o', 'x', 'y', '-', 'c', 'o', 'n', 'n', 'e', 'c',
+  't', 'i', 'o', 'n'
+};
+static const unsigned char llparse_blob12[] = {
+  'r', 'a', 'n', 's', 'f', 'e', 'r', '-', 'e', 'n', 'c',
+  'o', 'd', 'i', 'n', 'g'
+};
+static const unsigned char llparse_blob13[] = {
+  'p', 'g', 'r', 'a', 'd', 'e'
+};
+static const unsigned char llparse_blob14[] = {
+  0xd, 0xa
+};
+static const unsigned char llparse_blob15[] = {
+  'T', 'T', 'P', '/'
+};
+static const unsigned char llparse_blob16[] = {
+  0xd, 0xa, 0xd, 0xa, 'S', 'M', 0xd, 0xa, 0xd, 0xa
+};
+static const unsigned char llparse_blob17[] = {
+  'C', 'E', '/'
+};
+static const unsigned char llparse_blob18[] = {
+  'T', 'S', 'P', '/'
+};
+static const unsigned char llparse_blob19[] = {
+  'N', 'O', 'U', 'N', 'C', 'E'
+};
+static const unsigned char llparse_blob20[] = {
+  'I', 'N', 'D'
+};
+static const unsigned char llparse_blob21[] = {
+  'E', 'C', 'K', 'O', 'U', 'T'
+};
+static const unsigned char llparse_blob22[] = {
+  'N', 'E', 'C', 'T'
+};
+static const unsigned char llparse_blob23[] = {
+  'E', 'T', 'E'
+};
+static const unsigned char llparse_blob24[] = {
+  'C', 'R', 'I', 'B', 'E'
+};
+static const unsigned char llparse_blob25[] = {
+  'L', 'U', 'S', 'H'
+};
+static const unsigned char llparse_blob26[] = {
+  'E', 'T'
+};
+static const unsigned char llparse_blob27[] = {
+  'P', 'A', 'R', 'A', 'M', 'E', 'T', 'E', 'R'
+};
+static const unsigned char llparse_blob28[] = {
+  'E', 'A', 'D'
+};
+static const unsigned char llparse_blob29[] = {
+  'N', 'K'
+};
+static const unsigned char llparse_blob30[] = {
+  'C', 'K'
+};
+static const unsigned char llparse_blob31[] = {
+  'S', 'E', 'A', 'R', 'C', 'H'
+};
+static const unsigned char llparse_blob32[] = {
+  'R', 'G', 'E'
+};
+static const unsigned char llparse_blob33[] = {
+  'C', 'T', 'I', 'V', 'I', 'T', 'Y'
+};
+static const unsigned char llparse_blob34[] = {
+  'L', 'E', 'N', 'D', 'A', 'R'
+};
+static const unsigned char llparse_blob35[] = {
+  'V', 'E'
+};
+static const unsigned char llparse_blob36[] = {
+  'O', 'T', 'I', 'F', 'Y'
+};
+static const unsigned char llparse_blob37[] = {
+  'P', 'T', 'I', 'O', 'N', 'S'
+};
+static const unsigned char llparse_blob38[] = {
+  'C', 'H'
+};
+static const unsigned char llparse_blob39[] = {
+  'S', 'E'
+};
+static const unsigned char llparse_blob40[] = {
+  'A', 'Y'
+};
+static const unsigned char llparse_blob41[] = {
+  'S', 'T'
+};
+static const unsigned char llparse_blob42[] = {
+  'I', 'N', 'D'
+};
+static const unsigned char llparse_blob43[] = {
+  'A', 'T', 'C', 'H'
+};
+static const unsigned char llparse_blob44[] = {
+  'G', 'E'
+};
+static const unsigned char llparse_blob45[] = {
+  'I', 'N', 'D'
+};
+static const unsigned char llparse_blob46[] = {
+  'O', 'R', 'D'
+};
+static const unsigned char llparse_blob47[] = {
+  'I', 'R', 'E', 'C', 'T'
+};
+static const unsigned char llparse_blob48[] = {
+  'O', 'R', 'T'
+};
+static const unsigned char llparse_blob49[] = {
+  'R', 'C', 'H'
+};
+static const unsigned char llparse_blob50[] = {
+  'P', 'A', 'R', 'A', 'M', 'E', 'T', 'E', 'R'
+};
+static const unsigned char llparse_blob51[] = {
+  'U', 'R', 'C', 'E'
+};
+static const unsigned char llparse_blob52[] = {
+  'B', 'S', 'C', 'R', 'I', 'B', 'E'
+};
+static const unsigned char llparse_blob53[] = {
+  'A', 'R', 'D', 'O', 'W', 'N'
+};
+static const unsigned char llparse_blob54[] = {
+  'A', 'C', 'E'
+};
+static const unsigned char llparse_blob55[] = {
+  'I', 'N', 'D'
+};
+static const unsigned char llparse_blob56[] = {
+  'N', 'K'
+};
+static const unsigned char llparse_blob57[] = {
+  'C', 'K'
+};
+static const unsigned char llparse_blob58[] = {
+  'U', 'B', 'S', 'C', 'R', 'I', 'B', 'E'
+};
+static const unsigned char llparse_blob59[] = {
+  'H', 'T', 'T', 'P', '/'
+};
+static const unsigned char llparse_blob60[] = {
+  'A', 'D'
+};
+static const unsigned char llparse_blob61[] = {
+  'T', 'P', '/'
+};
+
+enum llparse_match_status_e {
+  kMatchComplete,
+  kMatchPause,
+  kMatchMismatch
+};
+typedef enum llparse_match_status_e llparse_match_status_t;
+
+struct llparse_match_s {
+  llparse_match_status_t status;
+  const unsigned char* current;
+};
+typedef struct llparse_match_s llparse_match_t;
+
+static llparse_match_t llparse__match_sequence_to_lower(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp,
+    const unsigned char* seq, uint32_t seq_len) {
+  uint32_t index;
+  llparse_match_t res;
+
+  index = s->_index;
+  for (; p != endp; p++) {
+    unsigned char current;
+
+    current = ((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p));
+    if (current == seq[index]) {
+      if (++index == seq_len) {
+        res.status = kMatchComplete;
+        goto reset;
+      }
+    } else {
+      res.status = kMatchMismatch;
+      goto reset;
+    }
+  }
+  s->_index = index;
+  res.status = kMatchPause;
+  res.current = p;
+  return res;
+reset:
+  s->_index = 0;
+  res.current = p;
+  return res;
+}
+
+static llparse_match_t llparse__match_sequence_to_lower_unsafe(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp,
+    const unsigned char* seq, uint32_t seq_len) {
+  uint32_t index;
+  llparse_match_t res;
+
+  index = s->_index;
+  for (; p != endp; p++) {
+    unsigned char current;
+
+    current = ((*p) | 0x20);
+    if (current == seq[index]) {
+      if (++index == seq_len) {
+        res.status = kMatchComplete;
+        goto reset;
+      }
+    } else {
+      res.status = kMatchMismatch;
+      goto reset;
+    }
+  }
+  s->_index = index;
+  res.status = kMatchPause;
+  res.current = p;
+  return res;
+reset:
+  s->_index = 0;
+  res.current = p;
+  return res;
+}
+
+static llparse_match_t llparse__match_sequence_id(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp,
+    const unsigned char* seq, uint32_t seq_len) {
+  uint32_t index;
+  llparse_match_t res;
+
+  index = s->_index;
+  for (; p != endp; p++) {
+    unsigned char current;
+
+    current = *p;
+    if (current == seq[index]) {
+      if (++index == seq_len) {
+        res.status = kMatchComplete;
+        goto reset;
+      }
+    } else {
+      res.status = kMatchMismatch;
+      goto reset;
+    }
+  }
+  s->_index = index;
+  res.status = kMatchPause;
+  res.current = p;
+  return res;
+reset:
+  s->_index = 0;
+  res.current = p;
+  return res;
+}
+
+enum llparse_state_e {
+  s_error,
+  s_n_llhttp__internal__n_closed,
+  s_n_llhttp__internal__n_invoke_llhttp__after_message_complete,
+  s_n_llhttp__internal__n_pause_1,
+  s_n_llhttp__internal__n_invoke_is_equal_upgrade,
+  s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2,
+  s_n_llhttp__internal__n_chunk_data_almost_done_skip,
+  s_n_llhttp__internal__n_chunk_data_almost_done,
+  s_n_llhttp__internal__n_consume_content_length,
+  s_n_llhttp__internal__n_span_start_llhttp__on_body,
+  s_n_llhttp__internal__n_invoke_is_equal_content_length,
+  s_n_llhttp__internal__n_chunk_size_almost_done,
+  s_n_llhttp__internal__n_chunk_parameters,
+  s_n_llhttp__internal__n_chunk_size_otherwise,
+  s_n_llhttp__internal__n_chunk_size,
+  s_n_llhttp__internal__n_chunk_size_digit,
+  s_n_llhttp__internal__n_invoke_update_content_length,
+  s_n_llhttp__internal__n_consume_content_length_1,
+  s_n_llhttp__internal__n_span_start_llhttp__on_body_1,
+  s_n_llhttp__internal__n_eof,
+  s_n_llhttp__internal__n_span_start_llhttp__on_body_2,
+  s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete,
+  s_n_llhttp__internal__n_headers_almost_done,
+  s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete,
+  s_n_llhttp__internal__n_span_start_llhttp__on_header_value,
+  s_n_llhttp__internal__n_header_value_discard_lws,
+  s_n_llhttp__internal__n_header_value_discard_ws_almost_done,
+  s_n_llhttp__internal__n_header_value_lws,
+  s_n_llhttp__internal__n_header_value_almost_done,
+  s_n_llhttp__internal__n_header_value_lenient,
+  s_n_llhttp__internal__n_header_value_otherwise,
+  s_n_llhttp__internal__n_header_value_connection_token,
+  s_n_llhttp__internal__n_header_value_connection_ws,
+  s_n_llhttp__internal__n_header_value_connection_1,
+  s_n_llhttp__internal__n_header_value_connection_2,
+  s_n_llhttp__internal__n_header_value_connection_3,
+  s_n_llhttp__internal__n_header_value_connection,
+  s_n_llhttp__internal__n_error_17,
+  s_n_llhttp__internal__n_error_18,
+  s_n_llhttp__internal__n_header_value_content_length_ws,
+  s_n_llhttp__internal__n_header_value_content_length,
+  s_n_llhttp__internal__n_header_value_te_chunked_last,
+  s_n_llhttp__internal__n_header_value_te_token_ows,
+  s_n_llhttp__internal__n_header_value,
+  s_n_llhttp__internal__n_header_value_te_token,
+  s_n_llhttp__internal__n_header_value_te_chunked,
+  s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1,
+  s_n_llhttp__internal__n_header_value_discard_ws,
+  s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete,
+  s_n_llhttp__internal__n_header_field_general_otherwise,
+  s_n_llhttp__internal__n_header_field_general,
+  s_n_llhttp__internal__n_header_field_colon,
+  s_n_llhttp__internal__n_header_field_3,
+  s_n_llhttp__internal__n_header_field_4,
+  s_n_llhttp__internal__n_header_field_2,
+  s_n_llhttp__internal__n_header_field_1,
+  s_n_llhttp__internal__n_header_field_5,
+  s_n_llhttp__internal__n_header_field_6,
+  s_n_llhttp__internal__n_header_field_7,
+  s_n_llhttp__internal__n_header_field,
+  s_n_llhttp__internal__n_span_start_llhttp__on_header_field,
+  s_n_llhttp__internal__n_header_field_start,
+  s_n_llhttp__internal__n_url_skip_to_http09,
+  s_n_llhttp__internal__n_url_skip_lf_to_http09,
+  s_n_llhttp__internal__n_req_pri_upgrade,
+  s_n_llhttp__internal__n_req_http_complete_1,
+  s_n_llhttp__internal__n_req_http_complete,
+  s_n_llhttp__internal__n_req_http_minor,
+  s_n_llhttp__internal__n_req_http_dot,
+  s_n_llhttp__internal__n_req_http_major,
+  s_n_llhttp__internal__n_req_http_start_1,
+  s_n_llhttp__internal__n_req_http_start_2,
+  s_n_llhttp__internal__n_req_http_start_3,
+  s_n_llhttp__internal__n_req_http_start,
+  s_n_llhttp__internal__n_url_skip_to_http,
+  s_n_llhttp__internal__n_url_fragment,
+  s_n_llhttp__internal__n_span_end_stub_query_3,
+  s_n_llhttp__internal__n_url_query,
+  s_n_llhttp__internal__n_url_query_or_fragment,
+  s_n_llhttp__internal__n_url_path,
+  s_n_llhttp__internal__n_span_start_stub_path_2,
+  s_n_llhttp__internal__n_span_start_stub_path,
+  s_n_llhttp__internal__n_span_start_stub_path_1,
+  s_n_llhttp__internal__n_url_server_with_at,
+  s_n_llhttp__internal__n_url_server,
+  s_n_llhttp__internal__n_url_schema_delim_1,
+  s_n_llhttp__internal__n_url_schema_delim,
+  s_n_llhttp__internal__n_span_end_stub_schema,
+  s_n_llhttp__internal__n_url_schema,
+  s_n_llhttp__internal__n_url_start,
+  s_n_llhttp__internal__n_span_start_llhttp__on_url_1,
+  s_n_llhttp__internal__n_span_start_llhttp__on_url,
+  s_n_llhttp__internal__n_req_spaces_before_url,
+  s_n_llhttp__internal__n_req_first_space_before_url,
+  s_n_llhttp__internal__n_start_req_2,
+  s_n_llhttp__internal__n_start_req_3,
+  s_n_llhttp__internal__n_start_req_1,
+  s_n_llhttp__internal__n_start_req_4,
+  s_n_llhttp__internal__n_start_req_6,
+  s_n_llhttp__internal__n_start_req_8,
+  s_n_llhttp__internal__n_start_req_9,
+  s_n_llhttp__internal__n_start_req_7,
+  s_n_llhttp__internal__n_start_req_5,
+  s_n_llhttp__internal__n_start_req_12,
+  s_n_llhttp__internal__n_start_req_13,
+  s_n_llhttp__internal__n_start_req_11,
+  s_n_llhttp__internal__n_start_req_10,
+  s_n_llhttp__internal__n_start_req_14,
+  s_n_llhttp__internal__n_start_req_17,
+  s_n_llhttp__internal__n_start_req_16,
+  s_n_llhttp__internal__n_start_req_15,
+  s_n_llhttp__internal__n_start_req_18,
+  s_n_llhttp__internal__n_start_req_20,
+  s_n_llhttp__internal__n_start_req_21,
+  s_n_llhttp__internal__n_start_req_19,
+  s_n_llhttp__internal__n_start_req_23,
+  s_n_llhttp__internal__n_start_req_24,
+  s_n_llhttp__internal__n_start_req_26,
+  s_n_llhttp__internal__n_start_req_28,
+  s_n_llhttp__internal__n_start_req_29,
+  s_n_llhttp__internal__n_start_req_27,
+  s_n_llhttp__internal__n_start_req_25,
+  s_n_llhttp__internal__n_start_req_30,
+  s_n_llhttp__internal__n_start_req_22,
+  s_n_llhttp__internal__n_start_req_31,
+  s_n_llhttp__internal__n_start_req_32,
+  s_n_llhttp__internal__n_start_req_35,
+  s_n_llhttp__internal__n_start_req_36,
+  s_n_llhttp__internal__n_start_req_34,
+  s_n_llhttp__internal__n_start_req_37,
+  s_n_llhttp__internal__n_start_req_38,
+  s_n_llhttp__internal__n_start_req_42,
+  s_n_llhttp__internal__n_start_req_43,
+  s_n_llhttp__internal__n_start_req_41,
+  s_n_llhttp__internal__n_start_req_40,
+  s_n_llhttp__internal__n_start_req_39,
+  s_n_llhttp__internal__n_start_req_45,
+  s_n_llhttp__internal__n_start_req_44,
+  s_n_llhttp__internal__n_start_req_33,
+  s_n_llhttp__internal__n_start_req_48,
+  s_n_llhttp__internal__n_start_req_49,
+  s_n_llhttp__internal__n_start_req_50,
+  s_n_llhttp__internal__n_start_req_51,
+  s_n_llhttp__internal__n_start_req_47,
+  s_n_llhttp__internal__n_start_req_46,
+  s_n_llhttp__internal__n_start_req_54,
+  s_n_llhttp__internal__n_start_req_56,
+  s_n_llhttp__internal__n_start_req_57,
+  s_n_llhttp__internal__n_start_req_55,
+  s_n_llhttp__internal__n_start_req_53,
+  s_n_llhttp__internal__n_start_req_58,
+  s_n_llhttp__internal__n_start_req_59,
+  s_n_llhttp__internal__n_start_req_52,
+  s_n_llhttp__internal__n_start_req_61,
+  s_n_llhttp__internal__n_start_req_62,
+  s_n_llhttp__internal__n_start_req_60,
+  s_n_llhttp__internal__n_start_req_65,
+  s_n_llhttp__internal__n_start_req_67,
+  s_n_llhttp__internal__n_start_req_68,
+  s_n_llhttp__internal__n_start_req_66,
+  s_n_llhttp__internal__n_start_req_69,
+  s_n_llhttp__internal__n_start_req_64,
+  s_n_llhttp__internal__n_start_req_63,
+  s_n_llhttp__internal__n_start_req,
+  s_n_llhttp__internal__n_invoke_llhttp__on_status_complete,
+  s_n_llhttp__internal__n_res_line_almost_done,
+  s_n_llhttp__internal__n_res_status,
+  s_n_llhttp__internal__n_span_start_llhttp__on_status,
+  s_n_llhttp__internal__n_res_status_start,
+  s_n_llhttp__internal__n_res_status_code_otherwise,
+  s_n_llhttp__internal__n_res_status_code,
+  s_n_llhttp__internal__n_res_http_end,
+  s_n_llhttp__internal__n_res_http_minor,
+  s_n_llhttp__internal__n_res_http_dot,
+  s_n_llhttp__internal__n_res_http_major,
+  s_n_llhttp__internal__n_start_res,
+  s_n_llhttp__internal__n_req_or_res_method_2,
+  s_n_llhttp__internal__n_req_or_res_method_3,
+  s_n_llhttp__internal__n_req_or_res_method_1,
+  s_n_llhttp__internal__n_req_or_res_method,
+  s_n_llhttp__internal__n_start_req_or_res,
+  s_n_llhttp__internal__n_invoke_load_type,
+  s_n_llhttp__internal__n_start,
+};
+typedef enum llparse_state_e llparse_state_t;
+
+int llhttp__on_url(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__on_header_field(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__on_header_value(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__on_body(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__on_status(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__internal__c_update_finish(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->finish = 2;
+  return 0;
+}
+
+int llhttp__on_message_begin(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__internal__c_load_type(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return state->type;
+}
+
+int llhttp__internal__c_store_method(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp,
+    int match) {
+  state->method = match;
+  return 0;
+}
+
+int llhttp__internal__c_is_equal_method(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return state->method == 5;
+}
+
+int llhttp__internal__c_update_http_major(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->http_major = 0;
+  return 0;
+}
+
+int llhttp__internal__c_update_http_minor(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->http_minor = 9;
+  return 0;
+}
+
+int llhttp__on_url_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__internal__c_test_flags(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return (state->flags & 128) == 128;
+}
+
+int llhttp__on_chunk_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__on_message_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__internal__c_is_equal_upgrade(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return state->upgrade == 1;
+}
+
+int llhttp__after_message_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__internal__c_update_finish_1(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->finish = 0;
+  return 0;
+}
+
+int llhttp__internal__c_test_lenient_flags(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return (state->lenient_flags & 4) == 4;
+}
+
+int llhttp__internal__c_test_flags_1(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return (state->flags & 544) == 544;
+}
+
+int llhttp__internal__c_test_lenient_flags_1(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return (state->lenient_flags & 2) == 2;
+}
+
+int llhttp__before_headers_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__on_headers_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__after_headers_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__internal__c_update_content_length(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->content_length = 0;
+  return 0;
+}
+
+int llhttp__internal__c_mul_add_content_length(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp,
+    int match) {
+  /* Multiplication overflow */
+  if (state->content_length > 0xffffffffffffffffULL / 16) {
+    return 1;
+  }
+  
+  state->content_length *= 16;
+  
+  /* Addition overflow */
+  if (match >= 0) {
+    if (state->content_length > 0xffffffffffffffffULL - match) {
+      return 1;
+    }
+  } else {
+    if (state->content_length < 0ULL - match) {
+      return 1;
+    }
+  }
+  state->content_length += match;
+  return 0;
+}
+
+int llhttp__on_chunk_header(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__internal__c_is_equal_content_length(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return state->content_length == 0;
+}
+
+int llhttp__internal__c_or_flags(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags |= 128;
+  return 0;
+}
+
+int llhttp__internal__c_update_finish_3(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->finish = 1;
+  return 0;
+}
+
+int llhttp__internal__c_or_flags_1(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags |= 64;
+  return 0;
+}
+
+int llhttp__internal__c_update_upgrade(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->upgrade = 1;
+  return 0;
+}
+
+int llhttp__internal__c_store_header_state(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp,
+    int match) {
+  state->header_state = match;
+  return 0;
+}
+
+int llhttp__on_header_field_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__internal__c_load_header_state(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return state->header_state;
+}
+
+int llhttp__internal__c_or_flags_3(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags |= 1;
+  return 0;
+}
+
+int llhttp__internal__c_update_header_state(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->header_state = 1;
+  return 0;
+}
+
+int llhttp__on_header_value_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__internal__c_or_flags_4(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags |= 2;
+  return 0;
+}
+
+int llhttp__internal__c_or_flags_5(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags |= 4;
+  return 0;
+}
+
+int llhttp__internal__c_or_flags_6(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags |= 8;
+  return 0;
+}
+
+int llhttp__internal__c_update_header_state_2(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->header_state = 6;
+  return 0;
+}
+
+int llhttp__internal__c_test_lenient_flags_2(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return (state->lenient_flags & 1) == 1;
+}
+
+int llhttp__internal__c_update_header_state_4(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->header_state = 0;
+  return 0;
+}
+
+int llhttp__internal__c_update_header_state_5(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->header_state = 5;
+  return 0;
+}
+
+int llhttp__internal__c_update_header_state_6(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->header_state = 7;
+  return 0;
+}
+
+int llhttp__internal__c_test_flags_2(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return (state->flags & 32) == 32;
+}
+
+int llhttp__internal__c_mul_add_content_length_1(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp,
+    int match) {
+  /* Multiplication overflow */
+  if (state->content_length > 0xffffffffffffffffULL / 10) {
+    return 1;
+  }
+  
+  state->content_length *= 10;
+  
+  /* Addition overflow */
+  if (match >= 0) {
+    if (state->content_length > 0xffffffffffffffffULL - match) {
+      return 1;
+    }
+  } else {
+    if (state->content_length < 0ULL - match) {
+      return 1;
+    }
+  }
+  state->content_length += match;
+  return 0;
+}
+
+int llhttp__internal__c_or_flags_15(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags |= 32;
+  return 0;
+}
+
+int llhttp__internal__c_or_flags_16(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags |= 512;
+  return 0;
+}
+
+int llhttp__internal__c_and_flags(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags &= -9;
+  return 0;
+}
+
+int llhttp__internal__c_update_header_state_7(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->header_state = 8;
+  return 0;
+}
+
+int llhttp__internal__c_or_flags_17(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->flags |= 16;
+  return 0;
+}
+
+int llhttp__internal__c_load_method(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  return state->method;
+}
+
+int llhttp__internal__c_store_http_major(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp,
+    int match) {
+  state->http_major = match;
+  return 0;
+}
+
+int llhttp__internal__c_store_http_minor(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp,
+    int match) {
+  state->http_minor = match;
+  return 0;
+}
+
+int llhttp__internal__c_update_status_code(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->status_code = 0;
+  return 0;
+}
+
+int llhttp__internal__c_mul_add_status_code(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp,
+    int match) {
+  /* Multiplication overflow */
+  if (state->status_code > 0xffff / 10) {
+    return 1;
+  }
+  
+  state->status_code *= 10;
+  
+  /* Addition overflow */
+  if (match >= 0) {
+    if (state->status_code > 0xffff - match) {
+      return 1;
+    }
+  } else {
+    if (state->status_code < 0 - match) {
+      return 1;
+    }
+  }
+  state->status_code += match;
+  
+  /* Enforce maximum */
+  if (state->status_code > 999) {
+    return 1;
+  }
+  return 0;
+}
+
+int llhttp__on_status_complete(
+    llhttp__internal_t* s, const unsigned char* p,
+    const unsigned char* endp);
+
+int llhttp__internal__c_update_type(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->type = 1;
+  return 0;
+}
+
+int llhttp__internal__c_update_type_1(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  state->type = 2;
+  return 0;
+}
+
+int llhttp__internal_init(llhttp__internal_t* state) {
+  memset(state, 0, sizeof(*state));
+  state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_start;
+  return 0;
+}
+
+static llparse_state_t llhttp__internal__run(
+    llhttp__internal_t* state,
+    const unsigned char* p,
+    const unsigned char* endp) {
+  int match;
+  switch ((llparse_state_t) (intptr_t) state->_current) {
+    case s_n_llhttp__internal__n_closed:
+    s_n_llhttp__internal__n_closed: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_closed;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_closed;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_llhttp__after_message_complete:
+    s_n_llhttp__internal__n_invoke_llhttp__after_message_complete: {
+      switch (llhttp__after_message_complete(state, p, endp)) {
+        case 1:
+          goto s_n_llhttp__internal__n_invoke_update_finish_2;
+        default:
+          goto s_n_llhttp__internal__n_invoke_update_finish_1;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_pause_1:
+    s_n_llhttp__internal__n_pause_1: {
+      state->error = 0x16;
+      state->reason = "Pause on CONNECT/Upgrade";
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_message_complete;
+      return s_error;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_is_equal_upgrade:
+    s_n_llhttp__internal__n_invoke_is_equal_upgrade: {
+      switch (llhttp__internal__c_is_equal_upgrade(state, p, endp)) {
+        case 0:
+          goto s_n_llhttp__internal__n_invoke_llhttp__after_message_complete;
+        default:
+          goto s_n_llhttp__internal__n_pause_1;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2:
+    s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2: {
+      switch (llhttp__on_message_complete(state, p, endp)) {
+        case 0:
+          goto s_n_llhttp__internal__n_invoke_is_equal_upgrade;
+        case 21:
+          goto s_n_llhttp__internal__n_pause_5;
+        default:
+          goto s_n_llhttp__internal__n_error_9;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_chunk_data_almost_done_skip:
+    s_n_llhttp__internal__n_chunk_data_almost_done_skip: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_chunk_data_almost_done_skip;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_chunk_data_almost_done:
+    s_n_llhttp__internal__n_chunk_data_almost_done: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_chunk_data_almost_done;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_chunk_data_almost_done_skip;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_consume_content_length:
+    s_n_llhttp__internal__n_consume_content_length: {
+      size_t avail;
+      size_t need;
+      
+      avail = endp - p;
+      need = state->content_length;
+      if (avail >= need) {
+        p += need;
+        state->content_length = 0;
+        goto s_n_llhttp__internal__n_span_end_llhttp__on_body;
+      }
+      
+      state->content_length -= avail;
+      return s_n_llhttp__internal__n_consume_content_length;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_llhttp__on_body:
+    s_n_llhttp__internal__n_span_start_llhttp__on_body: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_llhttp__on_body;
+      }
+      state->_span_pos0 = (void*) p;
+      state->_span_cb0 = llhttp__on_body;
+      goto s_n_llhttp__internal__n_consume_content_length;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_is_equal_content_length:
+    s_n_llhttp__internal__n_invoke_is_equal_content_length: {
+      switch (llhttp__internal__c_is_equal_content_length(state, p, endp)) {
+        case 0:
+          goto s_n_llhttp__internal__n_span_start_llhttp__on_body;
+        default:
+          goto s_n_llhttp__internal__n_invoke_or_flags;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_chunk_size_almost_done:
+    s_n_llhttp__internal__n_chunk_size_almost_done: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_chunk_size_almost_done;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_header;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_chunk_parameters:
+    s_n_llhttp__internal__n_chunk_parameters: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_chunk_parameters;
+      }
+      switch (*p) {
+        case 13: {
+          p++;
+          goto s_n_llhttp__internal__n_chunk_size_almost_done;
+        }
+        default: {
+          p++;
+          goto s_n_llhttp__internal__n_chunk_parameters;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_chunk_size_otherwise:
+    s_n_llhttp__internal__n_chunk_size_otherwise: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_chunk_size_otherwise;
+      }
+      switch (*p) {
+        case 13: {
+          p++;
+          goto s_n_llhttp__internal__n_chunk_size_almost_done;
+        }
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_chunk_parameters;
+        }
+        case ';': {
+          p++;
+          goto s_n_llhttp__internal__n_chunk_parameters;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_6;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_chunk_size:
+    s_n_llhttp__internal__n_chunk_size: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_chunk_size;
+      }
+      switch (*p) {
+        case '0': {
+          p++;
+          match = 0;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '1': {
+          p++;
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '2': {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '3': {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '4': {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '5': {
+          p++;
+          match = 5;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '6': {
+          p++;
+          match = 6;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '7': {
+          p++;
+          match = 7;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '8': {
+          p++;
+          match = 8;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '9': {
+          p++;
+          match = 9;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'A': {
+          p++;
+          match = 10;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'B': {
+          p++;
+          match = 11;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'C': {
+          p++;
+          match = 12;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'D': {
+          p++;
+          match = 13;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'E': {
+          p++;
+          match = 14;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'F': {
+          p++;
+          match = 15;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'a': {
+          p++;
+          match = 10;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'b': {
+          p++;
+          match = 11;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'c': {
+          p++;
+          match = 12;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'd': {
+          p++;
+          match = 13;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'e': {
+          p++;
+          match = 14;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'f': {
+          p++;
+          match = 15;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_chunk_size_otherwise;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_chunk_size_digit:
+    s_n_llhttp__internal__n_chunk_size_digit: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_chunk_size_digit;
+      }
+      switch (*p) {
+        case '0': {
+          p++;
+          match = 0;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '1': {
+          p++;
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '2': {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '3': {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '4': {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '5': {
+          p++;
+          match = 5;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '6': {
+          p++;
+          match = 6;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '7': {
+          p++;
+          match = 7;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '8': {
+          p++;
+          match = 8;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case '9': {
+          p++;
+          match = 9;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'A': {
+          p++;
+          match = 10;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'B': {
+          p++;
+          match = 11;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'C': {
+          p++;
+          match = 12;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'D': {
+          p++;
+          match = 13;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'E': {
+          p++;
+          match = 14;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'F': {
+          p++;
+          match = 15;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'a': {
+          p++;
+          match = 10;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'b': {
+          p++;
+          match = 11;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'c': {
+          p++;
+          match = 12;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'd': {
+          p++;
+          match = 13;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'e': {
+          p++;
+          match = 14;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        case 'f': {
+          p++;
+          match = 15;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_8;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_update_content_length:
+    s_n_llhttp__internal__n_invoke_update_content_length: {
+      switch (llhttp__internal__c_update_content_length(state, p, endp)) {
+        default:
+          goto s_n_llhttp__internal__n_chunk_size_digit;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_consume_content_length_1:
+    s_n_llhttp__internal__n_consume_content_length_1: {
+      size_t avail;
+      size_t need;
+      
+      avail = endp - p;
+      need = state->content_length;
+      if (avail >= need) {
+        p += need;
+        state->content_length = 0;
+        goto s_n_llhttp__internal__n_span_end_llhttp__on_body_1;
+      }
+      
+      state->content_length -= avail;
+      return s_n_llhttp__internal__n_consume_content_length_1;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_llhttp__on_body_1:
+    s_n_llhttp__internal__n_span_start_llhttp__on_body_1: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_llhttp__on_body_1;
+      }
+      state->_span_pos0 = (void*) p;
+      state->_span_cb0 = llhttp__on_body;
+      goto s_n_llhttp__internal__n_consume_content_length_1;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_eof:
+    s_n_llhttp__internal__n_eof: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_eof;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_eof;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_llhttp__on_body_2:
+    s_n_llhttp__internal__n_span_start_llhttp__on_body_2: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_llhttp__on_body_2;
+      }
+      state->_span_pos0 = (void*) p;
+      state->_span_cb0 = llhttp__on_body;
+      goto s_n_llhttp__internal__n_eof;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete:
+    s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete: {
+      switch (llhttp__after_headers_complete(state, p, endp)) {
+        case 1:
+          goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_1;
+        case 2:
+          goto s_n_llhttp__internal__n_invoke_update_content_length;
+        case 3:
+          goto s_n_llhttp__internal__n_span_start_llhttp__on_body_1;
+        case 4:
+          goto s_n_llhttp__internal__n_invoke_update_finish_3;
+        case 5:
+          goto s_n_llhttp__internal__n_error_10;
+        default:
+          goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_headers_almost_done:
+    s_n_llhttp__internal__n_headers_almost_done: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_headers_almost_done;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_invoke_test_flags;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete:
+    s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete: {
+      switch (llhttp__on_header_value_complete(state, p, endp)) {
+        default:
+          goto s_n_llhttp__internal__n_header_field_start;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_llhttp__on_header_value:
+    s_n_llhttp__internal__n_span_start_llhttp__on_header_value: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_llhttp__on_header_value;
+      }
+      state->_span_pos0 = (void*) p;
+      state->_span_cb0 = llhttp__on_header_value;
+      goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_discard_lws:
+    s_n_llhttp__internal__n_header_value_discard_lws: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_discard_lws;
+      }
+      switch (*p) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_discard_ws;
+        }
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_discard_ws;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_load_header_state;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_discard_ws_almost_done:
+    s_n_llhttp__internal__n_header_value_discard_ws_almost_done: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_discard_ws_almost_done;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_header_value_discard_lws;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_lws:
+    s_n_llhttp__internal__n_header_value_lws: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_lws;
+      }
+      switch (*p) {
+        case 9: {
+          goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1;
+        }
+        case ' ': {
+          goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_load_header_state_3;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_almost_done:
+    s_n_llhttp__internal__n_header_value_almost_done: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_almost_done;
+      }
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_lws;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_14;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_lenient:
+    s_n_llhttp__internal__n_header_value_lenient: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_lenient;
+      }
+      switch (*p) {
+        case 10: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_1;
+        }
+        case 13: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_3;
+        }
+        default: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_lenient;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_otherwise:
+    s_n_llhttp__internal__n_header_value_otherwise: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_otherwise;
+      }
+      switch (*p) {
+        case 10: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_1;
+        }
+        case 13: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_2;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_test_lenient_flags_2;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_connection_token:
+    s_n_llhttp__internal__n_header_value_connection_token: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_connection_token;
+      }
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_connection_token;
+        }
+        case 2: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_connection;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_header_value_otherwise;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_connection_ws:
+    s_n_llhttp__internal__n_header_value_connection_ws: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_connection_ws;
+      }
+      switch (*p) {
+        case 10: {
+          goto s_n_llhttp__internal__n_header_value_otherwise;
+        }
+        case 13: {
+          goto s_n_llhttp__internal__n_header_value_otherwise;
+        }
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_connection_ws;
+        }
+        case ',': {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_load_header_state_4;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_4;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_connection_1:
+    s_n_llhttp__internal__n_header_value_connection_1: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_connection_1;
+      }
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob3, 4);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_update_header_state_2;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_header_value_connection_1;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_header_value_connection_token;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_connection_2:
+    s_n_llhttp__internal__n_header_value_connection_2: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_connection_2;
+      }
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob4, 9);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_update_header_state_5;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_header_value_connection_2;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_header_value_connection_token;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_connection_3:
+    s_n_llhttp__internal__n_header_value_connection_3: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_connection_3;
+      }
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob5, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_update_header_state_6;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_header_value_connection_3;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_header_value_connection_token;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_connection:
+    s_n_llhttp__internal__n_header_value_connection: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_connection;
+      }
+      switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_connection;
+        }
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_connection;
+        }
+        case 'c': {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_connection_1;
+        }
+        case 'k': {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_connection_2;
+        }
+        case 'u': {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_connection_3;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_header_value_connection_token;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_error_17:
+    s_n_llhttp__internal__n_error_17: {
+      state->error = 0xb;
+      state->reason = "Content-Length overflow";
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_error;
+      return s_error;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_error_18:
+    s_n_llhttp__internal__n_error_18: {
+      state->error = 0xb;
+      state->reason = "Invalid character in Content-Length";
+      state->error_pos = (const char*) p;
+      state->_current = (void*) (intptr_t) s_error;
+      return s_error;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_content_length_ws:
+    s_n_llhttp__internal__n_header_value_content_length_ws: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_content_length_ws;
+      }
+      switch (*p) {
+        case 10: {
+          goto s_n_llhttp__internal__n_invoke_or_flags_15;
+        }
+        case 13: {
+          goto s_n_llhttp__internal__n_invoke_or_flags_15;
+        }
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_content_length_ws;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_5;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_content_length:
+    s_n_llhttp__internal__n_header_value_content_length: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_content_length;
+      }
+      switch (*p) {
+        case '0': {
+          p++;
+          match = 0;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1;
+        }
+        case '1': {
+          p++;
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1;
+        }
+        case '2': {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1;
+        }
+        case '3': {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1;
+        }
+        case '4': {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1;
+        }
+        case '5': {
+          p++;
+          match = 5;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1;
+        }
+        case '6': {
+          p++;
+          match = 6;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1;
+        }
+        case '7': {
+          p++;
+          match = 7;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1;
+        }
+        case '8': {
+          p++;
+          match = 8;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1;
+        }
+        case '9': {
+          p++;
+          match = 9;
+          goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_header_value_content_length_ws;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_te_chunked_last:
+    s_n_llhttp__internal__n_header_value_te_chunked_last: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_te_chunked_last;
+      }
+      switch (*p) {
+        case 10: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_7;
+        }
+        case 13: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_7;
+        }
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_te_chunked_last;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_header_value_te_chunked;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_te_token_ows:
+    s_n_llhttp__internal__n_header_value_te_token_ows: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_te_token_ows;
+      }
+      switch (*p) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_te_token_ows;
+        }
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_te_token_ows;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_header_value_te_chunked;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value:
+    s_n_llhttp__internal__n_header_value: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value;
+      }
+      #ifdef __SSE4_2__
+      if (endp - p >= 16) {
+        __m128i ranges;
+        __m128i input;
+        int avail;
+        int match_len;
+      
+        /* Load input */
+        input = _mm_loadu_si128((__m128i const*) p);
+        ranges = _mm_loadu_si128((__m128i const*) llparse_blob7);
+      
+        /* Find first character that does not match `ranges` */
+        match_len = _mm_cmpestri(ranges, 6,
+            input, 16,
+            _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
+              _SIDD_NEGATIVE_POLARITY);
+      
+        if (match_len != 0) {
+          p += match_len;
+          goto s_n_llhttp__internal__n_header_value;
+        }
+        goto s_n_llhttp__internal__n_header_value_otherwise;
+      }
+      #endif  /* __SSE4_2__ */
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_header_value_otherwise;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_te_token:
+    s_n_llhttp__internal__n_header_value_te_token: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_te_token;
+      }
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_te_token;
+        }
+        case 2: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_te_token_ows;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_8;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_te_chunked:
+    s_n_llhttp__internal__n_header_value_te_chunked: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_te_chunked;
+      }
+      match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob6, 7);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_te_chunked_last;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_header_value_te_chunked;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_header_value_te_token;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1:
+    s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1;
+      }
+      state->_span_pos0 = (void*) p;
+      state->_span_cb0 = llhttp__on_header_value;
+      goto s_n_llhttp__internal__n_invoke_load_header_state_2;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_value_discard_ws:
+    s_n_llhttp__internal__n_header_value_discard_ws: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_value_discard_ws;
+      }
+      switch (*p) {
+        case 9: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_discard_ws;
+        }
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_discard_lws;
+        }
+        case 13: {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_discard_ws_almost_done;
+        }
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_header_value_discard_ws;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete:
+    s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete: {
+      switch (llhttp__on_header_field_complete(state, p, endp)) {
+        default:
+          goto s_n_llhttp__internal__n_header_value_discard_ws;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_general_otherwise:
+    s_n_llhttp__internal__n_header_field_general_otherwise: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_general_otherwise;
+      }
+      switch (*p) {
+        case ':': {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_header_field_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_19;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_general:
+    s_n_llhttp__internal__n_header_field_general: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_general;
+      }
+      #ifdef __SSE4_2__
+      if (endp - p >= 16) {
+        __m128i ranges;
+        __m128i input;
+        int avail;
+        int match_len;
+      
+        /* Load input */
+        input = _mm_loadu_si128((__m128i const*) p);
+        ranges = _mm_loadu_si128((__m128i const*) llparse_blob8);
+      
+        /* Find first character that does not match `ranges` */
+        match_len = _mm_cmpestri(ranges, 16,
+            input, 16,
+            _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
+              _SIDD_NEGATIVE_POLARITY);
+      
+        if (match_len != 0) {
+          p += match_len;
+          goto s_n_llhttp__internal__n_header_field_general;
+        }
+        ranges = _mm_loadu_si128((__m128i const*) llparse_blob9);
+      
+        /* Find first character that does not match `ranges` */
+        match_len = _mm_cmpestri(ranges, 2,
+            input, 16,
+            _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
+              _SIDD_NEGATIVE_POLARITY);
+      
+        if (match_len != 0) {
+          p += match_len;
+          goto s_n_llhttp__internal__n_header_field_general;
+        }
+        goto s_n_llhttp__internal__n_header_field_general_otherwise;
+      }
+      #endif  /* __SSE4_2__ */
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_general;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_header_field_general_otherwise;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_colon:
+    s_n_llhttp__internal__n_header_field_colon: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_colon;
+      }
+      switch (*p) {
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_colon;
+        }
+        case ':': {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_header_field;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_9;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_3:
+    s_n_llhttp__internal__n_header_field_3: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_3;
+      }
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob2, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_store_header_state;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_header_field_3;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_10;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_4:
+    s_n_llhttp__internal__n_header_field_4: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_4;
+      }
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob10, 10);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_store_header_state;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_header_field_4;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_10;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_2:
+    s_n_llhttp__internal__n_header_field_2: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_2;
+      }
+      switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) {
+        case 'n': {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_3;
+        }
+        case 't': {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_4;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_10;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_1:
+    s_n_llhttp__internal__n_header_field_1: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_1;
+      }
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob1, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_2;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_header_field_1;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_10;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_5:
+    s_n_llhttp__internal__n_header_field_5: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_5;
+      }
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob11, 15);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_store_header_state;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_header_field_5;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_10;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_6:
+    s_n_llhttp__internal__n_header_field_6: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_6;
+      }
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob12, 16);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_store_header_state;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_header_field_6;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_10;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_7:
+    s_n_llhttp__internal__n_header_field_7: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_7;
+      }
+      match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob13, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_store_header_state;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_header_field_7;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_10;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field:
+    s_n_llhttp__internal__n_header_field: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field;
+      }
+      switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) {
+        case 'c': {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_1;
+        }
+        case 'p': {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_5;
+        }
+        case 't': {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_6;
+        }
+        case 'u': {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_7;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_update_header_state_10;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_llhttp__on_header_field:
+    s_n_llhttp__internal__n_span_start_llhttp__on_header_field: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_llhttp__on_header_field;
+      }
+      state->_span_pos0 = (void*) p;
+      state->_span_cb0 = llhttp__on_header_field;
+      goto s_n_llhttp__internal__n_header_field;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_header_field_start:
+    s_n_llhttp__internal__n_header_field_start: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_header_field_start;
+      }
+      switch (*p) {
+        case 10: {
+          goto s_n_llhttp__internal__n_headers_almost_done;
+        }
+        case 13: {
+          p++;
+          goto s_n_llhttp__internal__n_headers_almost_done;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_span_start_llhttp__on_header_field;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_skip_to_http09:
+    s_n_llhttp__internal__n_url_skip_to_http09: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_skip_to_http09;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_invoke_update_http_major;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_skip_lf_to_http09:
+    s_n_llhttp__internal__n_url_skip_lf_to_http09: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_skip_lf_to_http09;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob14, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_update_http_major;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_url_skip_lf_to_http09;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_20;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_pri_upgrade:
+    s_n_llhttp__internal__n_req_pri_upgrade: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_pri_upgrade;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob16, 10);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_error_23;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_req_pri_upgrade;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_24;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_complete_1:
+    s_n_llhttp__internal__n_req_http_complete_1: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_complete_1;
+      }
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_start;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_22;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_complete:
+    s_n_llhttp__internal__n_req_http_complete: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_complete;
+      }
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_header_field_start;
+        }
+        case 13: {
+          p++;
+          goto s_n_llhttp__internal__n_req_http_complete_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_22;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_minor:
+    s_n_llhttp__internal__n_req_http_minor: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_minor;
+      }
+      switch (*p) {
+        case '0': {
+          p++;
+          match = 0;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor;
+        }
+        case '1': {
+          p++;
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor;
+        }
+        case '2': {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor;
+        }
+        case '3': {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor;
+        }
+        case '4': {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor;
+        }
+        case '5': {
+          p++;
+          match = 5;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor;
+        }
+        case '6': {
+          p++;
+          match = 6;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor;
+        }
+        case '7': {
+          p++;
+          match = 7;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor;
+        }
+        case '8': {
+          p++;
+          match = 8;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor;
+        }
+        case '9': {
+          p++;
+          match = 9;
+          goto s_n_llhttp__internal__n_invoke_store_http_minor;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_25;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_dot:
+    s_n_llhttp__internal__n_req_http_dot: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_dot;
+      }
+      switch (*p) {
+        case '.': {
+          p++;
+          goto s_n_llhttp__internal__n_req_http_minor;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_26;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_major:
+    s_n_llhttp__internal__n_req_http_major: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_major;
+      }
+      switch (*p) {
+        case '0': {
+          p++;
+          match = 0;
+          goto s_n_llhttp__internal__n_invoke_store_http_major;
+        }
+        case '1': {
+          p++;
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_store_http_major;
+        }
+        case '2': {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_store_http_major;
+        }
+        case '3': {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_store_http_major;
+        }
+        case '4': {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_store_http_major;
+        }
+        case '5': {
+          p++;
+          match = 5;
+          goto s_n_llhttp__internal__n_invoke_store_http_major;
+        }
+        case '6': {
+          p++;
+          match = 6;
+          goto s_n_llhttp__internal__n_invoke_store_http_major;
+        }
+        case '7': {
+          p++;
+          match = 7;
+          goto s_n_llhttp__internal__n_invoke_store_http_major;
+        }
+        case '8': {
+          p++;
+          match = 8;
+          goto s_n_llhttp__internal__n_invoke_store_http_major;
+        }
+        case '9': {
+          p++;
+          match = 9;
+          goto s_n_llhttp__internal__n_invoke_store_http_major;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_27;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_start_1:
+    s_n_llhttp__internal__n_req_http_start_1: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_start_1;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob15, 4);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_load_method;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_req_http_start_1;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_30;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_start_2:
+    s_n_llhttp__internal__n_req_http_start_2: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_start_2;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob17, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_load_method_2;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_req_http_start_2;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_30;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_start_3:
+    s_n_llhttp__internal__n_req_http_start_3: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_start_3;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob18, 4);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_invoke_load_method_3;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_req_http_start_3;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_30;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_http_start:
+    s_n_llhttp__internal__n_req_http_start: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_http_start;
+      }
+      switch (*p) {
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_req_http_start;
+        }
+        case 'H': {
+          p++;
+          goto s_n_llhttp__internal__n_req_http_start_1;
+        }
+        case 'I': {
+          p++;
+          goto s_n_llhttp__internal__n_req_http_start_2;
+        }
+        case 'R': {
+          p++;
+          goto s_n_llhttp__internal__n_req_http_start_3;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_30;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_skip_to_http:
+    s_n_llhttp__internal__n_url_skip_to_http: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_skip_to_http;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_invoke_llhttp__on_url_complete_1;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_fragment:
+    s_n_llhttp__internal__n_url_fragment: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_fragment;
+      }
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          p++;
+          goto s_n_llhttp__internal__n_url_fragment;
+        }
+        case 2: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_6;
+        }
+        case 3: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_7;
+        }
+        case 4: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_8;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_31;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_end_stub_query_3:
+    s_n_llhttp__internal__n_span_end_stub_query_3: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_end_stub_query_3;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_url_fragment;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_query:
+    s_n_llhttp__internal__n_url_query: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        4, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_query;
+      }
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          p++;
+          goto s_n_llhttp__internal__n_url_query;
+        }
+        case 2: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_9;
+        }
+        case 3: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_10;
+        }
+        case 4: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_11;
+        }
+        case 5: {
+          goto s_n_llhttp__internal__n_span_end_stub_query_3;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_32;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_query_or_fragment:
+    s_n_llhttp__internal__n_url_query_or_fragment: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_query_or_fragment;
+      }
+      switch (*p) {
+        case 10: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_3;
+        }
+        case 13: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_4;
+        }
+        case ' ': {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_5;
+        }
+        case '#': {
+          p++;
+          goto s_n_llhttp__internal__n_url_fragment;
+        }
+        case '?': {
+          p++;
+          goto s_n_llhttp__internal__n_url_query;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_33;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_path:
+    s_n_llhttp__internal__n_url_path: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_path;
+      }
+      #ifdef __SSE4_2__
+      if (endp - p >= 16) {
+        __m128i ranges;
+        __m128i input;
+        int avail;
+        int match_len;
+      
+        /* Load input */
+        input = _mm_loadu_si128((__m128i const*) p);
+        ranges = _mm_loadu_si128((__m128i const*) llparse_blob0);
+      
+        /* Find first character that does not match `ranges` */
+        match_len = _mm_cmpestri(ranges, 12,
+            input, 16,
+            _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
+              _SIDD_NEGATIVE_POLARITY);
+      
+        if (match_len != 0) {
+          p += match_len;
+          goto s_n_llhttp__internal__n_url_path;
+        }
+        goto s_n_llhttp__internal__n_url_query_or_fragment;
+      }
+      #endif  /* __SSE4_2__ */
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          p++;
+          goto s_n_llhttp__internal__n_url_path;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_url_query_or_fragment;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_stub_path_2:
+    s_n_llhttp__internal__n_span_start_stub_path_2: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_stub_path_2;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_url_path;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_stub_path:
+    s_n_llhttp__internal__n_span_start_stub_path: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_stub_path;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_url_path;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_stub_path_1:
+    s_n_llhttp__internal__n_span_start_stub_path_1: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_stub_path_1;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_url_path;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_server_with_at:
+    s_n_llhttp__internal__n_url_server_with_at: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        3, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 6,
+        7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 4,
+        0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_server_with_at;
+      }
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_12;
+        }
+        case 2: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_13;
+        }
+        case 3: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_14;
+        }
+        case 4: {
+          p++;
+          goto s_n_llhttp__internal__n_url_server;
+        }
+        case 5: {
+          goto s_n_llhttp__internal__n_span_start_stub_path_1;
+        }
+        case 6: {
+          p++;
+          goto s_n_llhttp__internal__n_url_query;
+        }
+        case 7: {
+          p++;
+          goto s_n_llhttp__internal__n_error_34;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_35;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_server:
+    s_n_llhttp__internal__n_url_server: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        3, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 6,
+        7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 4,
+        0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_server;
+      }
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url;
+        }
+        case 2: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_1;
+        }
+        case 3: {
+          goto s_n_llhttp__internal__n_span_end_llhttp__on_url_2;
+        }
+        case 4: {
+          p++;
+          goto s_n_llhttp__internal__n_url_server;
+        }
+        case 5: {
+          goto s_n_llhttp__internal__n_span_start_stub_path;
+        }
+        case 6: {
+          p++;
+          goto s_n_llhttp__internal__n_url_query;
+        }
+        case 7: {
+          p++;
+          goto s_n_llhttp__internal__n_url_server_with_at;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_36;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_schema_delim_1:
+    s_n_llhttp__internal__n_url_schema_delim_1: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_schema_delim_1;
+      }
+      switch (*p) {
+        case '/': {
+          p++;
+          goto s_n_llhttp__internal__n_url_server;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_38;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_schema_delim:
+    s_n_llhttp__internal__n_url_schema_delim: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_schema_delim;
+      }
+      switch (*p) {
+        case 10: {
+          p++;
+          goto s_n_llhttp__internal__n_error_37;
+        }
+        case 13: {
+          p++;
+          goto s_n_llhttp__internal__n_error_37;
+        }
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_error_37;
+        }
+        case '/': {
+          p++;
+          goto s_n_llhttp__internal__n_url_schema_delim_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_38;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_end_stub_schema:
+    s_n_llhttp__internal__n_span_end_stub_schema: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_end_stub_schema;
+      }
+      p++;
+      goto s_n_llhttp__internal__n_url_schema_delim;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_schema:
+    s_n_llhttp__internal__n_url_schema: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+        0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+        0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_schema;
+      }
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          p++;
+          goto s_n_llhttp__internal__n_error_37;
+        }
+        case 2: {
+          goto s_n_llhttp__internal__n_span_end_stub_schema;
+        }
+        case 3: {
+          p++;
+          goto s_n_llhttp__internal__n_url_schema;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_39;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_url_start:
+    s_n_llhttp__internal__n_url_start: {
+      static uint8_t lookup_table[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+        0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+      };
+      if (p == endp) {
+        return s_n_llhttp__internal__n_url_start;
+      }
+      switch (lookup_table[(uint8_t) *p]) {
+        case 1: {
+          p++;
+          goto s_n_llhttp__internal__n_error_37;
+        }
+        case 2: {
+          goto s_n_llhttp__internal__n_span_start_stub_path_2;
+        }
+        case 3: {
+          goto s_n_llhttp__internal__n_url_schema;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_40;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_llhttp__on_url_1:
+    s_n_llhttp__internal__n_span_start_llhttp__on_url_1: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_llhttp__on_url_1;
+      }
+      state->_span_pos0 = (void*) p;
+      state->_span_cb0 = llhttp__on_url;
+      goto s_n_llhttp__internal__n_url_start;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_span_start_llhttp__on_url:
+    s_n_llhttp__internal__n_span_start_llhttp__on_url: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_span_start_llhttp__on_url;
+      }
+      state->_span_pos0 = (void*) p;
+      state->_span_cb0 = llhttp__on_url;
+      goto s_n_llhttp__internal__n_url_server;
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_spaces_before_url:
+    s_n_llhttp__internal__n_req_spaces_before_url: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_spaces_before_url;
+      }
+      switch (*p) {
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_req_spaces_before_url;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_invoke_is_equal_method;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_req_first_space_before_url:
+    s_n_llhttp__internal__n_req_first_space_before_url: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_req_first_space_before_url;
+      }
+      switch (*p) {
+        case ' ': {
+          p++;
+          goto s_n_llhttp__internal__n_req_spaces_before_url;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_41;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_2:
+    s_n_llhttp__internal__n_start_req_2: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_2;
+      }
+      switch (*p) {
+        case 'L': {
+          p++;
+          match = 19;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_3:
+    s_n_llhttp__internal__n_start_req_3: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_3;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob19, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 36;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_3;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_1:
+    s_n_llhttp__internal__n_start_req_1: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_1;
+      }
+      switch (*p) {
+        case 'C': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_2;
+        }
+        case 'N': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_3;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_4:
+    s_n_llhttp__internal__n_start_req_4: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_4;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob20, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 16;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_4;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_6:
+    s_n_llhttp__internal__n_start_req_6: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_6;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob21, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 22;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_6;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_8:
+    s_n_llhttp__internal__n_start_req_8: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_8;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob22, 4);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 5;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_8;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_9:
+    s_n_llhttp__internal__n_start_req_9: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_9;
+      }
+      switch (*p) {
+        case 'Y': {
+          p++;
+          match = 8;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_7:
+    s_n_llhttp__internal__n_start_req_7: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_7;
+      }
+      switch (*p) {
+        case 'N': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_8;
+        }
+        case 'P': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_9;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_5:
+    s_n_llhttp__internal__n_start_req_5: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_5;
+      }
+      switch (*p) {
+        case 'H': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_6;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_7;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_12:
+    s_n_llhttp__internal__n_start_req_12: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_12;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob23, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 0;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_12;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_13:
+    s_n_llhttp__internal__n_start_req_13: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_13;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob24, 5);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 35;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_13;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_11:
+    s_n_llhttp__internal__n_start_req_11: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_11;
+      }
+      switch (*p) {
+        case 'L': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_12;
+        }
+        case 'S': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_13;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_10:
+    s_n_llhttp__internal__n_start_req_10: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_10;
+      }
+      switch (*p) {
+        case 'E': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_11;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_14:
+    s_n_llhttp__internal__n_start_req_14: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_14;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob25, 4);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 45;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_14;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_17:
+    s_n_llhttp__internal__n_start_req_17: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_17;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob27, 9);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 41;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_17;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_16:
+    s_n_llhttp__internal__n_start_req_16: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_16;
+      }
+      switch (*p) {
+        case '_': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_17;
+        }
+        default: {
+          match = 1;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_15:
+    s_n_llhttp__internal__n_start_req_15: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_15;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob26, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_16;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_15;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_18:
+    s_n_llhttp__internal__n_start_req_18: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_18;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob28, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 2;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_18;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_20:
+    s_n_llhttp__internal__n_start_req_20: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_20;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob29, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 31;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_20;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_21:
+    s_n_llhttp__internal__n_start_req_21: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_21;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob30, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 9;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_21;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_19:
+    s_n_llhttp__internal__n_start_req_19: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_19;
+      }
+      switch (*p) {
+        case 'I': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_20;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_21;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_23:
+    s_n_llhttp__internal__n_start_req_23: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_23;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob31, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 24;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_23;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_24:
+    s_n_llhttp__internal__n_start_req_24: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_24;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob32, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 23;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_24;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_26:
+    s_n_llhttp__internal__n_start_req_26: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_26;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob33, 7);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 21;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_26;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_28:
+    s_n_llhttp__internal__n_start_req_28: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_28;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob34, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 30;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_28;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_29:
+    s_n_llhttp__internal__n_start_req_29: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_29;
+      }
+      switch (*p) {
+        case 'L': {
+          p++;
+          match = 10;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_27:
+    s_n_llhttp__internal__n_start_req_27: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_27;
+      }
+      switch (*p) {
+        case 'A': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_28;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_29;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_25:
+    s_n_llhttp__internal__n_start_req_25: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_25;
+      }
+      switch (*p) {
+        case 'A': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_26;
+        }
+        case 'C': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_27;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_30:
+    s_n_llhttp__internal__n_start_req_30: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_30;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob35, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 11;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_30;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_22:
+    s_n_llhttp__internal__n_start_req_22: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_22;
+      }
+      switch (*p) {
+        case '-': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_23;
+        }
+        case 'E': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_24;
+        }
+        case 'K': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_25;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_30;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_31:
+    s_n_llhttp__internal__n_start_req_31: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_31;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob36, 5);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 25;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_31;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_32:
+    s_n_llhttp__internal__n_start_req_32: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_32;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob37, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 6;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_32;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_35:
+    s_n_llhttp__internal__n_start_req_35: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_35;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob38, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 28;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_35;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_36:
+    s_n_llhttp__internal__n_start_req_36: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_36;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob39, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 39;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_36;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_34:
+    s_n_llhttp__internal__n_start_req_34: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_34;
+      }
+      switch (*p) {
+        case 'T': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_35;
+        }
+        case 'U': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_36;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_37:
+    s_n_llhttp__internal__n_start_req_37: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_37;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob40, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 38;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_37;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_38:
+    s_n_llhttp__internal__n_start_req_38: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_38;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob41, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 3;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_38;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_42:
+    s_n_llhttp__internal__n_start_req_42: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_42;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob42, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 12;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_42;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_43:
+    s_n_llhttp__internal__n_start_req_43: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_43;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob43, 4);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 13;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_43;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_41:
+    s_n_llhttp__internal__n_start_req_41: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_41;
+      }
+      switch (*p) {
+        case 'F': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_42;
+        }
+        case 'P': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_43;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_40:
+    s_n_llhttp__internal__n_start_req_40: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_40;
+      }
+      switch (*p) {
+        case 'P': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_41;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_39:
+    s_n_llhttp__internal__n_start_req_39: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_39;
+      }
+      switch (*p) {
+        case 'I': {
+          p++;
+          match = 34;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_40;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_45:
+    s_n_llhttp__internal__n_start_req_45: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_45;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob44, 2);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 29;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_45;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_44:
+    s_n_llhttp__internal__n_start_req_44: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_44;
+      }
+      switch (*p) {
+        case 'R': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_45;
+        }
+        case 'T': {
+          p++;
+          match = 4;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_33:
+    s_n_llhttp__internal__n_start_req_33: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_33;
+      }
+      switch (*p) {
+        case 'A': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_34;
+        }
+        case 'L': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_37;
+        }
+        case 'O': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_38;
+        }
+        case 'R': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_39;
+        }
+        case 'U': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_44;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_48:
+    s_n_llhttp__internal__n_start_req_48: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_48;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob45, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 17;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_48;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_49:
+    s_n_llhttp__internal__n_start_req_49: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_49;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob46, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 44;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_49;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_50:
+    s_n_llhttp__internal__n_start_req_50: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_50;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob47, 5);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 43;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_50;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_51:
+    s_n_llhttp__internal__n_start_req_51: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_51;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob48, 3);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 20;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_51;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_47:
+    s_n_llhttp__internal__n_start_req_47: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_47;
+      }
+      switch (*p) {
+        case 'B': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_48;
+        }
+        case 'C': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_49;
+        }
+        case 'D': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_33;
+          goto s_n_llhttp__internal__n_start_req_50;
         }
-        case 'T': {
+        case 'P': {
           p++;
-          match = 4;
-          goto s_n_llhttp__internal__n_invoke_store_method_1;
+          goto s_n_llhttp__internal__n_start_req_51;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_25:
-    s_n_llhttp__internal__n_start_req_25: {
+    case s_n_llhttp__internal__n_start_req_46:
+    s_n_llhttp__internal__n_start_req_46: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_25;
+        return s_n_llhttp__internal__n_start_req_46;
       }
       switch (*p) {
-        case 'A': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_26;
-        }
-        case 'O': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_27;
-        }
-        case 'R': {
-          p++;
-          goto s_n_llhttp__internal__n_start_req_28;
-        }
-        case 'U': {
+        case 'E': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_32;
+          goto s_n_llhttp__internal__n_start_req_47;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_36:
-    s_n_llhttp__internal__n_start_req_36: {
+    case s_n_llhttp__internal__n_start_req_54:
+    s_n_llhttp__internal__n_start_req_54: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_36;
+        return s_n_llhttp__internal__n_start_req_54;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob39, 3);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob49, 3);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 17;
+          match = 14;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_36;
+          return s_n_llhttp__internal__n_start_req_54;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_37:
-    s_n_llhttp__internal__n_start_req_37: {
+    case s_n_llhttp__internal__n_start_req_56:
+    s_n_llhttp__internal__n_start_req_56: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_56;
+      }
+      switch (*p) {
+        case 'P': {
+          p++;
+          match = 37;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_57:
+    s_n_llhttp__internal__n_start_req_57: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_37;
+        return s_n_llhttp__internal__n_start_req_57;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob40, 3);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob50, 9);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
           p++;
-          match = 20;
+          match = 42;
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_37;
+          return s_n_llhttp__internal__n_start_req_57;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_35:
-    s_n_llhttp__internal__n_start_req_35: {
+    case s_n_llhttp__internal__n_start_req_55:
+    s_n_llhttp__internal__n_start_req_55: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_35;
+        return s_n_llhttp__internal__n_start_req_55;
       }
       switch (*p) {
-        case 'B': {
+        case 'U': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_36;
+          goto s_n_llhttp__internal__n_start_req_56;
         }
-        case 'P': {
+        case '_': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_37;
+          goto s_n_llhttp__internal__n_start_req_57;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_34:
-    s_n_llhttp__internal__n_start_req_34: {
+    case s_n_llhttp__internal__n_start_req_53:
+    s_n_llhttp__internal__n_start_req_53: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_34;
+        return s_n_llhttp__internal__n_start_req_53;
       }
       switch (*p) {
-        case 'E': {
+        case 'A': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_35;
+          goto s_n_llhttp__internal__n_start_req_54;
         }
-        default: {
-          goto s_n_llhttp__internal__n_error_46;
-        }
-      }
-      /* UNREACHABLE */;
-      abort();
-    }
-    case s_n_llhttp__internal__n_start_req_39:
-    s_n_llhttp__internal__n_start_req_39: {
-      llparse_match_t match_seq;
-      
-      if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_39;
-      }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob41, 4);
-      p = match_seq.current;
-      switch (match_seq.status) {
-        case kMatchComplete: {
+        case 'T': {
           p++;
-          match = 14;
-          goto s_n_llhttp__internal__n_invoke_store_method_1;
+          goto s_n_llhttp__internal__n_start_req_55;
         }
-        case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_39;
-        }
-        case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_40:
-    s_n_llhttp__internal__n_start_req_40: {
+    case s_n_llhttp__internal__n_start_req_58:
+    s_n_llhttp__internal__n_start_req_58: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_40;
+        return s_n_llhttp__internal__n_start_req_58;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob42, 4);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob51, 4);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -4084,23 +12253,23 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_40;
+          return s_n_llhttp__internal__n_start_req_58;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_41:
-    s_n_llhttp__internal__n_start_req_41: {
+    case s_n_llhttp__internal__n_start_req_59:
+    s_n_llhttp__internal__n_start_req_59: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_41;
+        return s_n_llhttp__internal__n_start_req_59;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob43, 7);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob52, 7);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -4109,48 +12278,73 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_41;
+          return s_n_llhttp__internal__n_start_req_59;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_38:
-    s_n_llhttp__internal__n_start_req_38: {
+    case s_n_llhttp__internal__n_start_req_52:
+    s_n_llhttp__internal__n_start_req_52: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_38;
+        return s_n_llhttp__internal__n_start_req_52;
       }
       switch (*p) {
         case 'E': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_39;
+          goto s_n_llhttp__internal__n_start_req_53;
         }
         case 'O': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_40;
+          goto s_n_llhttp__internal__n_start_req_58;
         }
         case 'U': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_41;
+          goto s_n_llhttp__internal__n_start_req_59;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_42:
-    s_n_llhttp__internal__n_start_req_42: {
+    case s_n_llhttp__internal__n_start_req_61:
+    s_n_llhttp__internal__n_start_req_61: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_42;
+        return s_n_llhttp__internal__n_start_req_61;
+      }
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob53, 6);
+      p = match_seq.current;
+      switch (match_seq.status) {
+        case kMatchComplete: {
+          p++;
+          match = 40;
+          goto s_n_llhttp__internal__n_invoke_store_method_1;
+        }
+        case kMatchPause: {
+          return s_n_llhttp__internal__n_start_req_61;
+        }
+        case kMatchMismatch: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_62:
+    s_n_llhttp__internal__n_start_req_62: {
+      llparse_match_t match_seq;
+      
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_62;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob44, 4);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob54, 3);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -4159,23 +12353,44 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_42;
+          return s_n_llhttp__internal__n_start_req_62;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_45:
-    s_n_llhttp__internal__n_start_req_45: {
+    case s_n_llhttp__internal__n_start_req_60:
+    s_n_llhttp__internal__n_start_req_60: {
+      if (p == endp) {
+        return s_n_llhttp__internal__n_start_req_60;
+      }
+      switch (*p) {
+        case 'E': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_61;
+        }
+        case 'R': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_62;
+        }
+        default: {
+          goto s_n_llhttp__internal__n_error_49;
+        }
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
+    case s_n_llhttp__internal__n_start_req_65:
+    s_n_llhttp__internal__n_start_req_65: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_45;
+        return s_n_llhttp__internal__n_start_req_65;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob45, 3);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob55, 3);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -4184,23 +12399,23 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_45;
+          return s_n_llhttp__internal__n_start_req_65;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_47:
-    s_n_llhttp__internal__n_start_req_47: {
+    case s_n_llhttp__internal__n_start_req_67:
+    s_n_llhttp__internal__n_start_req_67: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_47;
+        return s_n_llhttp__internal__n_start_req_67;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob46, 2);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob56, 2);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -4209,23 +12424,23 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_47;
+          return s_n_llhttp__internal__n_start_req_67;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_48:
-    s_n_llhttp__internal__n_start_req_48: {
+    case s_n_llhttp__internal__n_start_req_68:
+    s_n_llhttp__internal__n_start_req_68: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_48;
+        return s_n_llhttp__internal__n_start_req_68;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob47, 2);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob57, 2);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -4234,44 +12449,44 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_48;
+          return s_n_llhttp__internal__n_start_req_68;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_46:
-    s_n_llhttp__internal__n_start_req_46: {
+    case s_n_llhttp__internal__n_start_req_66:
+    s_n_llhttp__internal__n_start_req_66: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_46;
+        return s_n_llhttp__internal__n_start_req_66;
       }
       switch (*p) {
         case 'I': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_47;
+          goto s_n_llhttp__internal__n_start_req_67;
         }
         case 'O': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_48;
+          goto s_n_llhttp__internal__n_start_req_68;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_49:
-    s_n_llhttp__internal__n_start_req_49: {
+    case s_n_llhttp__internal__n_start_req_69:
+    s_n_llhttp__internal__n_start_req_69: {
       llparse_match_t match_seq;
       
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_49;
+        return s_n_llhttp__internal__n_start_req_69;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob48, 8);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob58, 8);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -4280,52 +12495,52 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_method_1;
         }
         case kMatchPause: {
-          return s_n_llhttp__internal__n_start_req_49;
+          return s_n_llhttp__internal__n_start_req_69;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_44:
-    s_n_llhttp__internal__n_start_req_44: {
+    case s_n_llhttp__internal__n_start_req_64:
+    s_n_llhttp__internal__n_start_req_64: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_44;
+        return s_n_llhttp__internal__n_start_req_64;
       }
       switch (*p) {
         case 'B': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_45;
+          goto s_n_llhttp__internal__n_start_req_65;
         }
         case 'L': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_46;
+          goto s_n_llhttp__internal__n_start_req_66;
         }
         case 'S': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_49;
+          goto s_n_llhttp__internal__n_start_req_69;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
-    case s_n_llhttp__internal__n_start_req_43:
-    s_n_llhttp__internal__n_start_req_43: {
+    case s_n_llhttp__internal__n_start_req_63:
+    s_n_llhttp__internal__n_start_req_63: {
       if (p == endp) {
-        return s_n_llhttp__internal__n_start_req_43;
+        return s_n_llhttp__internal__n_start_req_63;
       }
       switch (*p) {
         case 'N': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_44;
+          goto s_n_llhttp__internal__n_start_req_64;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
@@ -4343,74 +12558,87 @@ static llparse_state_t llhttp__internal__run(
         }
         case 'B': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_2;
+          goto s_n_llhttp__internal__n_start_req_4;
         }
         case 'C': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_3;
+          goto s_n_llhttp__internal__n_start_req_5;
         }
         case 'D': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_8;
+          goto s_n_llhttp__internal__n_start_req_10;
+        }
+        case 'F': {
+          p++;
+          goto s_n_llhttp__internal__n_start_req_14;
         }
         case 'G': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_9;
+          goto s_n_llhttp__internal__n_start_req_15;
         }
         case 'H': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_10;
+          goto s_n_llhttp__internal__n_start_req_18;
         }
         case 'L': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_11;
+          goto s_n_llhttp__internal__n_start_req_19;
         }
         case 'M': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_14;
+          goto s_n_llhttp__internal__n_start_req_22;
         }
         case 'N': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_23;
+          goto s_n_llhttp__internal__n_start_req_31;
         }
         case 'O': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_24;
+          goto s_n_llhttp__internal__n_start_req_32;
         }
         case 'P': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_25;
+          goto s_n_llhttp__internal__n_start_req_33;
         }
         case 'R': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_34;
+          goto s_n_llhttp__internal__n_start_req_46;
         }
         case 'S': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_38;
+          goto s_n_llhttp__internal__n_start_req_52;
         }
         case 'T': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_42;
+          goto s_n_llhttp__internal__n_start_req_60;
         }
         case 'U': {
           p++;
-          goto s_n_llhttp__internal__n_start_req_43;
+          goto s_n_llhttp__internal__n_start_req_63;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_46;
+          goto s_n_llhttp__internal__n_error_49;
         }
       }
       /* UNREACHABLE */;
       abort();
     }
+    case s_n_llhttp__internal__n_invoke_llhttp__on_status_complete:
+    s_n_llhttp__internal__n_invoke_llhttp__on_status_complete: {
+      switch (llhttp__on_status_complete(state, p, endp)) {
+        default:
+          goto s_n_llhttp__internal__n_header_field_start;
+      }
+      /* UNREACHABLE */;
+      abort();
+    }
     case s_n_llhttp__internal__n_res_line_almost_done:
     s_n_llhttp__internal__n_res_line_almost_done: {
       if (p == endp) {
         return s_n_llhttp__internal__n_res_line_almost_done;
       }
       p++;
-      goto s_n_llhttp__internal__n_header_field_start;
+      goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete;
       /* UNREACHABLE */;
       abort();
     }
@@ -4453,7 +12681,7 @@ static llparse_state_t llhttp__internal__run(
       switch (*p) {
         case 10: {
           p++;
-          goto s_n_llhttp__internal__n_header_field_start;
+          goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete;
         }
         case 13: {
           p++;
@@ -4483,7 +12711,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_res_status_start;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_40;
+          goto s_n_llhttp__internal__n_error_43;
         }
       }
       /* UNREACHABLE */;
@@ -4563,7 +12791,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_update_status_code;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_41;
+          goto s_n_llhttp__internal__n_error_44;
         }
       }
       /* UNREACHABLE */;
@@ -4626,7 +12854,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_http_minor_1;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_42;
+          goto s_n_llhttp__internal__n_error_45;
         }
       }
       /* UNREACHABLE */;
@@ -4643,7 +12871,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_res_http_minor;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_43;
+          goto s_n_llhttp__internal__n_error_46;
         }
       }
       /* UNREACHABLE */;
@@ -4706,7 +12934,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_invoke_store_http_major_1;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_44;
+          goto s_n_llhttp__internal__n_error_47;
         }
       }
       /* UNREACHABLE */;
@@ -4719,7 +12947,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_start_res;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob49, 5);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob59, 5);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -4730,7 +12958,7 @@ static llparse_state_t llhttp__internal__run(
           return s_n_llhttp__internal__n_start_res;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_47;
+          goto s_n_llhttp__internal__n_error_50;
         }
       }
       /* UNREACHABLE */;
@@ -4743,7 +12971,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_req_or_res_method_2;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob50, 2);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob60, 2);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -4755,7 +12983,7 @@ static llparse_state_t llhttp__internal__run(
           return s_n_llhttp__internal__n_req_or_res_method_2;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_45;
+          goto s_n_llhttp__internal__n_error_48;
         }
       }
       /* UNREACHABLE */;
@@ -4768,7 +12996,7 @@ static llparse_state_t llhttp__internal__run(
       if (p == endp) {
         return s_n_llhttp__internal__n_req_or_res_method_3;
       }
-      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob51, 3);
+      match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob61, 3);
       p = match_seq.current;
       switch (match_seq.status) {
         case kMatchComplete: {
@@ -4779,7 +13007,7 @@ static llparse_state_t llhttp__internal__run(
           return s_n_llhttp__internal__n_req_or_res_method_3;
         }
         case kMatchMismatch: {
-          goto s_n_llhttp__internal__n_error_45;
+          goto s_n_llhttp__internal__n_error_48;
         }
       }
       /* UNREACHABLE */;
@@ -4800,7 +13028,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_req_or_res_method_3;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_45;
+          goto s_n_llhttp__internal__n_error_48;
         }
       }
       /* UNREACHABLE */;
@@ -4817,7 +13045,7 @@ static llparse_state_t llhttp__internal__run(
           goto s_n_llhttp__internal__n_req_or_res_method_1;
         }
         default: {
-          goto s_n_llhttp__internal__n_error_45;
+          goto s_n_llhttp__internal__n_error_48;
         }
       }
       /* UNREACHABLE */;
@@ -4877,19 +13105,37 @@ static llparse_state_t llhttp__internal__run(
       /* UNREACHABLE */
       abort();
   }
-  s_n_llhttp__internal__n_error_34: {
-    state->error = 0x7;
-    state->reason = "Invalid characters in url";
-    state->error_pos = (const char*) p;
-    state->_current = (void*) (intptr_t) s_error;
-    return s_error;
+  s_n_llhttp__internal__n_error_37: {
+    state->error = 0x7;
+    state->reason = "Invalid characters in url";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_update_finish_2: {
+    switch (llhttp__internal__c_update_finish_1(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_start;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_test_lenient_flags: {
+    switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) {
+      case 1:
+        goto s_n_llhttp__internal__n_invoke_update_finish_2;
+      default:
+        goto s_n_llhttp__internal__n_closed;
+    }
     /* UNREACHABLE */;
     abort();
   }
   s_n_llhttp__internal__n_invoke_update_finish_1: {
     switch (llhttp__internal__c_update_finish_1(state, p, endp)) {
       default:
-        goto s_n_llhttp__internal__n_start;
+        goto s_n_llhttp__internal__n_invoke_test_lenient_flags;
     }
     /* UNREACHABLE */;
     abort();
@@ -4921,7 +13167,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_13: {
+  s_n_llhttp__internal__n_error_12: {
     state->error = 0x14;
     state->reason = "`on_chunk_complete` callback error";
     state->error_pos = (const char*) p;
@@ -4937,7 +13183,7 @@ static llparse_state_t llhttp__internal__run(
       case 21:
         goto s_n_llhttp__internal__n_pause_7;
       default:
-        goto s_n_llhttp__internal__n_error_13;
+        goto s_n_llhttp__internal__n_error_12;
     }
     /* UNREACHABLE */;
     abort();
@@ -4951,15 +13197,6 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_12: {
-    state->error = 0x4;
-    state->reason = "Content-Length can't be present with chunked encoding";
-    state->error_pos = (const char*) p;
-    state->_current = (void*) (intptr_t) s_error;
-    return s_error;
-    /* UNREACHABLE */;
-    abort();
-  }
   s_n_llhttp__internal__n_pause_2: {
     state->error = 0x15;
     state->reason = "on_message_complete pause";
@@ -5129,8 +13366,8 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_invoke_update_finish_2: {
-    switch (llhttp__internal__c_update_finish_2(state, p, endp)) {
+  s_n_llhttp__internal__n_invoke_update_finish_3: {
+    switch (llhttp__internal__c_update_finish_3(state, p, endp)) {
       default:
         goto s_n_llhttp__internal__n_span_start_llhttp__on_body_2;
     }
@@ -5242,22 +13479,10 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_invoke_test_flags_3: {
-    switch (llhttp__internal__c_test_flags_3(state, p, endp)) {
-      case 1:
-        goto s_n_llhttp__internal__n_error_12;
-      default:
-        goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete;
-    }
-    /* UNREACHABLE */;
-    abort();
-  }
-  s_n_llhttp__internal__n_invoke_test_flags_2: {
-    switch (llhttp__internal__c_test_flags_2(state, p, endp)) {
+  s_n_llhttp__internal__n_invoke_test_lenient_flags_1: {
+    switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) {
       case 0:
         goto s_n_llhttp__internal__n_error_11;
-      case 1:
-        goto s_n_llhttp__internal__n_invoke_test_flags_3;
       default:
         goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete;
     }
@@ -5267,7 +13492,7 @@ static llparse_state_t llhttp__internal__run(
   s_n_llhttp__internal__n_invoke_test_flags_1: {
     switch (llhttp__internal__c_test_flags_1(state, p, endp)) {
       case 1:
-        goto s_n_llhttp__internal__n_invoke_test_flags_2;
+        goto s_n_llhttp__internal__n_invoke_test_lenient_flags_1;
       default:
         goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete;
     }
@@ -5284,7 +13509,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_14: {
+  s_n_llhttp__internal__n_error_13: {
     state->error = 0xb;
     state->reason = "Empty Content-Length";
     state->error_pos = (const char*) p;
@@ -5303,10 +13528,10 @@ static llparse_state_t llhttp__internal__run(
     if (err != 0) {
       state->error = err;
       state->error_pos = (const char*) p;
-      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_field_start;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete;
       return s_error;
     }
-    goto s_n_llhttp__internal__n_header_field_start;
+    goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete;
     /* UNREACHABLE */;
     abort();
   }
@@ -5369,7 +13594,7 @@ static llparse_state_t llhttp__internal__run(
   s_n_llhttp__internal__n_invoke_load_header_state: {
     switch (llhttp__internal__c_load_header_state(state, p, endp)) {
       case 2:
-        goto s_n_llhttp__internal__n_error_14;
+        goto s_n_llhttp__internal__n_error_13;
       default:
         goto s_n_llhttp__internal__n_invoke_load_header_state_1;
     }
@@ -5379,7 +13604,7 @@ static llparse_state_t llhttp__internal__run(
   s_n_llhttp__internal__n_invoke_update_header_state_1: {
     switch (llhttp__internal__c_update_header_state(state, p, endp)) {
       default:
-        goto s_n_llhttp__internal__n_header_field_start;
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete;
     }
     /* UNREACHABLE */;
     abort();
@@ -5411,7 +13636,7 @@ static llparse_state_t llhttp__internal__run(
   s_n_llhttp__internal__n_invoke_or_flags_10: {
     switch (llhttp__internal__c_or_flags_6(state, p, endp)) {
       default:
-        goto s_n_llhttp__internal__n_header_field_start;
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete;
     }
     /* UNREACHABLE */;
     abort();
@@ -5427,12 +13652,12 @@ static llparse_state_t llhttp__internal__run(
       case 8:
         goto s_n_llhttp__internal__n_invoke_or_flags_10;
       default:
-        goto s_n_llhttp__internal__n_header_field_start;
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete;
     }
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_15: {
+  s_n_llhttp__internal__n_error_14: {
     state->error = 0x3;
     state->reason = "Missing expected LF after header value";
     state->error_pos = (const char*) p;
@@ -5494,7 +13719,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_16: {
+  s_n_llhttp__internal__n_error_15: {
     state->error = 0xa;
     state->reason = "Invalid header value char";
     state->error_pos = (const char*) p;
@@ -5503,12 +13728,12 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_invoke_test_flags_4: {
-    switch (llhttp__internal__c_test_flags_2(state, p, endp)) {
+  s_n_llhttp__internal__n_invoke_test_lenient_flags_2: {
+    switch (llhttp__internal__c_test_lenient_flags_2(state, p, endp)) {
       case 1:
         goto s_n_llhttp__internal__n_header_value_lenient;
       default:
-        goto s_n_llhttp__internal__n_error_16;
+        goto s_n_llhttp__internal__n_error_15;
     }
     /* UNREACHABLE */;
     abort();
@@ -5611,10 +13836,10 @@ static llparse_state_t llhttp__internal__run(
     if (err != 0) {
       state->error = err;
       state->error_pos = (const char*) p;
-      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_18;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_17;
       return s_error;
     }
-    goto s_n_llhttp__internal__n_error_18;
+    goto s_n_llhttp__internal__n_error_17;
     /* UNREACHABLE */;
     abort();
   }
@@ -5628,18 +13853,10 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_invoke_update_header_state_7: {
-    switch (llhttp__internal__c_update_header_state_4(state, p, endp)) {
-      default:
-        goto s_n_llhttp__internal__n_header_value;
-    }
-    /* UNREACHABLE */;
-    abort();
-  }
   s_n_llhttp__internal__n_invoke_or_flags_15: {
     switch (llhttp__internal__c_or_flags_15(state, p, endp)) {
       default:
-        goto s_n_llhttp__internal__n_header_value_discard_rws;
+        goto s_n_llhttp__internal__n_header_value_otherwise;
     }
     /* UNREACHABLE */;
     abort();
@@ -5654,14 +13871,14 @@ static llparse_state_t llhttp__internal__run(
     if (err != 0) {
       state->error = err;
       state->error_pos = (const char*) p;
-      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_19;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_18;
       return s_error;
     }
-    goto s_n_llhttp__internal__n_error_19;
+    goto s_n_llhttp__internal__n_error_18;
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_17: {
+  s_n_llhttp__internal__n_error_16: {
     state->error = 0x4;
     state->reason = "Duplicate Content-Length";
     state->error_pos = (const char*) p;
@@ -5670,28 +13887,44 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_invoke_test_flags_5: {
-    switch (llhttp__internal__c_test_flags_5(state, p, endp)) {
+  s_n_llhttp__internal__n_invoke_test_flags_2: {
+    switch (llhttp__internal__c_test_flags_2(state, p, endp)) {
       case 0:
         goto s_n_llhttp__internal__n_header_value_content_length;
       default:
-        goto s_n_llhttp__internal__n_error_17;
+        goto s_n_llhttp__internal__n_error_16;
     }
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_invoke_update_header_state_8: {
-    switch (llhttp__internal__c_update_header_state_8(state, p, endp)) {
+  s_n_llhttp__internal__n_invoke_update_header_state_7: {
+    switch (llhttp__internal__c_update_header_state_7(state, p, endp)) {
       default:
         goto s_n_llhttp__internal__n_header_value_otherwise;
     }
     /* UNREACHABLE */;
     abort();
   }
+  s_n_llhttp__internal__n_invoke_update_header_state_8: {
+    switch (llhttp__internal__c_update_header_state_4(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_and_flags: {
+    switch (llhttp__internal__c_and_flags(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_value_te_chunked;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
   s_n_llhttp__internal__n_invoke_or_flags_16: {
     switch (llhttp__internal__c_or_flags_16(state, p, endp)) {
       default:
-        goto s_n_llhttp__internal__n_header_value_te_chunked;
+        goto s_n_llhttp__internal__n_invoke_and_flags;
     }
     /* UNREACHABLE */;
     abort();
@@ -5699,7 +13932,7 @@ static llparse_state_t llhttp__internal__run(
   s_n_llhttp__internal__n_invoke_or_flags_17: {
     switch (llhttp__internal__c_or_flags_17(state, p, endp)) {
       default:
-        goto s_n_llhttp__internal__n_invoke_update_header_state_7;
+        goto s_n_llhttp__internal__n_invoke_update_header_state_8;
     }
     /* UNREACHABLE */;
     abort();
@@ -5709,7 +13942,7 @@ static llparse_state_t llhttp__internal__run(
       case 1:
         goto s_n_llhttp__internal__n_header_value_connection;
       case 2:
-        goto s_n_llhttp__internal__n_invoke_test_flags_5;
+        goto s_n_llhttp__internal__n_invoke_test_flags_2;
       case 3:
         goto s_n_llhttp__internal__n_invoke_or_flags_16;
       case 4:
@@ -5730,11 +13963,11 @@ static llparse_state_t llhttp__internal__run(
     if (err != 0) {
       state->error = err;
       state->error_pos = (const char*) (p + 1);
-      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_discard_ws;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete;
       return s_error;
     }
     p++;
-    goto s_n_llhttp__internal__n_header_value_discard_ws;
+    goto s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete;
     /* UNREACHABLE */;
     abort();
   }
@@ -5748,15 +13981,15 @@ static llparse_state_t llhttp__internal__run(
     if (err != 0) {
       state->error = err;
       state->error_pos = (const char*) (p + 1);
-      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_discard_ws;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete;
       return s_error;
     }
     p++;
-    goto s_n_llhttp__internal__n_header_value_discard_ws;
+    goto s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete;
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_20: {
+  s_n_llhttp__internal__n_error_19: {
     state->error = 0xa;
     state->reason = "Invalid header token";
     state->error_pos = (const char*) p;
@@ -5789,10 +14022,18 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
+  s_n_llhttp__internal__n_invoke_llhttp__on_url_complete: {
+    switch (llhttp__on_url_complete(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_header_field_start;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
   s_n_llhttp__internal__n_invoke_update_http_minor: {
     switch (llhttp__internal__c_update_http_minor(state, p, endp)) {
       default:
-        goto s_n_llhttp__internal__n_header_field_start;
+        goto s_n_llhttp__internal__n_invoke_llhttp__on_url_complete;
     }
     /* UNREACHABLE */;
     abort();
@@ -5822,7 +14063,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_21: {
+  s_n_llhttp__internal__n_error_20: {
     state->error = 0x7;
     state->reason = "Expected CRLF";
     state->error_pos = (const char*) p;
@@ -5848,6 +14089,24 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
+  s_n_llhttp__internal__n_error_23: {
+    state->error = 0x17;
+    state->reason = "Pause on PRI/Upgrade";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_24: {
+    state->error = 0x9;
+    state->reason = "Expected HTTP/2 Connection Preface";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
   s_n_llhttp__internal__n_error_22: {
     state->error = 0x9;
     state->reason = "Expected CRLF after version";
@@ -5857,15 +14116,25 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
+  s_n_llhttp__internal__n_invoke_load_method_1: {
+    switch (llhttp__internal__c_load_method(state, p, endp)) {
+      case 34:
+        goto s_n_llhttp__internal__n_req_pri_upgrade;
+      default:
+        goto s_n_llhttp__internal__n_req_http_complete;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
   s_n_llhttp__internal__n_invoke_store_http_minor: {
     switch (llhttp__internal__c_store_http_minor(state, p, endp, match)) {
       default:
-        goto s_n_llhttp__internal__n_req_http_end;
+        goto s_n_llhttp__internal__n_invoke_load_method_1;
     }
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_23: {
+  s_n_llhttp__internal__n_error_25: {
     state->error = 0x9;
     state->reason = "Invalid minor version";
     state->error_pos = (const char*) p;
@@ -5874,7 +14143,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_24: {
+  s_n_llhttp__internal__n_error_26: {
     state->error = 0x9;
     state->reason = "Expected dot";
     state->error_pos = (const char*) p;
@@ -5891,7 +14160,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_25: {
+  s_n_llhttp__internal__n_error_27: {
     state->error = 0x9;
     state->reason = "Invalid major version";
     state->error_pos = (const char*) p;
@@ -5900,7 +14169,94 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_27: {
+  s_n_llhttp__internal__n_error_21: {
+    state->error = 0x8;
+    state->reason = "Invalid method for HTTP/x.x request";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_method: {
+    switch (llhttp__internal__c_load_method(state, p, endp)) {
+      case 0:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 1:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 2:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 3:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 4:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 5:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 6:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 7:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 8:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 9:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 10:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 11:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 12:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 13:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 14:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 15:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 16:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 17:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 18:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 19:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 20:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 21:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 22:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 23:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 24:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 25:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 26:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 27:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 28:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 29:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 30:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 31:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 32:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 33:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 34:
+        goto s_n_llhttp__internal__n_req_http_major;
+      default:
+        goto s_n_llhttp__internal__n_error_21;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_30: {
     state->error = 0x8;
     state->reason = "Expected HTTP/";
     state->error_pos = (const char*) p;
@@ -5909,7 +14265,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_26: {
+  s_n_llhttp__internal__n_error_28: {
     state->error = 0x8;
     state->reason = "Expected SOURCE method for ICE/x.x request";
     state->error_pos = (const char*) p;
@@ -5918,12 +14274,65 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_invoke_is_equal_method_1: {
-    switch (llhttp__internal__c_is_equal_method_1(state, p, endp)) {
-      case 0:
-        goto s_n_llhttp__internal__n_error_26;
+  s_n_llhttp__internal__n_invoke_load_method_2: {
+    switch (llhttp__internal__c_load_method(state, p, endp)) {
+      case 33:
+        goto s_n_llhttp__internal__n_req_http_major;
       default:
+        goto s_n_llhttp__internal__n_error_28;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_error_29: {
+    state->error = 0x8;
+    state->reason = "Invalid method for RTSP/x.x request";
+    state->error_pos = (const char*) p;
+    state->_current = (void*) (intptr_t) s_error;
+    return s_error;
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_load_method_3: {
+    switch (llhttp__internal__c_load_method(state, p, endp)) {
+      case 1:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 3:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 6:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 35:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 36:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 37:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 38:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 39:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 40:
         goto s_n_llhttp__internal__n_req_http_major;
+      case 41:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 42:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 43:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 44:
+        goto s_n_llhttp__internal__n_req_http_major;
+      case 45:
+        goto s_n_llhttp__internal__n_req_http_major;
+      default:
+        goto s_n_llhttp__internal__n_error_29;
+    }
+    /* UNREACHABLE */;
+    abort();
+  }
+  s_n_llhttp__internal__n_invoke_llhttp__on_url_complete_1: {
+    switch (llhttp__on_url_complete(state, p, endp)) {
+      default:
+        goto s_n_llhttp__internal__n_req_http_start;
     }
     /* UNREACHABLE */;
     abort();
@@ -5996,7 +14405,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_28: {
+  s_n_llhttp__internal__n_error_31: {
     state->error = 0x7;
     state->reason = "Invalid char in url fragment start";
     state->error_pos = (const char*) p;
@@ -6056,7 +14465,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_29: {
+  s_n_llhttp__internal__n_error_32: {
     state->error = 0x7;
     state->reason = "Invalid char in url query";
     state->error_pos = (const char*) p;
@@ -6065,7 +14474,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_30: {
+  s_n_llhttp__internal__n_error_33: {
     state->error = 0x7;
     state->reason = "Invalid char in url path";
     state->error_pos = (const char*) p;
@@ -6176,7 +14585,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_31: {
+  s_n_llhttp__internal__n_error_34: {
     state->error = 0x7;
     state->reason = "Double @ in url";
     state->error_pos = (const char*) p;
@@ -6185,7 +14594,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_32: {
+  s_n_llhttp__internal__n_error_35: {
     state->error = 0x7;
     state->reason = "Unexpected char in url server";
     state->error_pos = (const char*) p;
@@ -6194,7 +14603,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_33: {
+  s_n_llhttp__internal__n_error_36: {
     state->error = 0x7;
     state->reason = "Unexpected char in url server";
     state->error_pos = (const char*) p;
@@ -6203,7 +14612,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_35: {
+  s_n_llhttp__internal__n_error_38: {
     state->error = 0x7;
     state->reason = "Unexpected char in url schema";
     state->error_pos = (const char*) p;
@@ -6212,7 +14621,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_36: {
+  s_n_llhttp__internal__n_error_39: {
     state->error = 0x7;
     state->reason = "Unexpected char in url schema";
     state->error_pos = (const char*) p;
@@ -6221,7 +14630,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_37: {
+  s_n_llhttp__internal__n_error_40: {
     state->error = 0x7;
     state->reason = "Unexpected start char in url";
     state->error_pos = (const char*) p;
@@ -6240,7 +14649,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_38: {
+  s_n_llhttp__internal__n_error_41: {
     state->error = 0x6;
     state->reason = "Expected space after method";
     state->error_pos = (const char*) p;
@@ -6257,7 +14666,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_46: {
+  s_n_llhttp__internal__n_error_49: {
     state->error = 0x6;
     state->reason = "Invalid method encountered";
     state->error_pos = (const char*) p;
@@ -6266,7 +14675,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_39: {
+  s_n_llhttp__internal__n_error_42: {
     state->error = 0xd;
     state->reason = "Response overflow";
     state->error_pos = (const char*) p;
@@ -6278,7 +14687,7 @@ static llparse_state_t llhttp__internal__run(
   s_n_llhttp__internal__n_invoke_mul_add_status_code: {
     switch (llhttp__internal__c_mul_add_status_code(state, p, endp, match)) {
       case 1:
-        goto s_n_llhttp__internal__n_error_39;
+        goto s_n_llhttp__internal__n_error_42;
       default:
         goto s_n_llhttp__internal__n_res_status_code;
     }
@@ -6295,11 +14704,11 @@ static llparse_state_t llhttp__internal__run(
     if (err != 0) {
       state->error = err;
       state->error_pos = (const char*) (p + 1);
-      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_field_start;
+      state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_status_complete;
       return s_error;
     }
     p++;
-    goto s_n_llhttp__internal__n_header_field_start;
+    goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete;
     /* UNREACHABLE */;
     abort();
   }
@@ -6321,7 +14730,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_40: {
+  s_n_llhttp__internal__n_error_43: {
     state->error = 0xd;
     state->reason = "Invalid response status";
     state->error_pos = (const char*) p;
@@ -6338,7 +14747,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_41: {
+  s_n_llhttp__internal__n_error_44: {
     state->error = 0x9;
     state->reason = "Expected space after version";
     state->error_pos = (const char*) p;
@@ -6355,7 +14764,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_42: {
+  s_n_llhttp__internal__n_error_45: {
     state->error = 0x9;
     state->reason = "Invalid minor version";
     state->error_pos = (const char*) p;
@@ -6364,7 +14773,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_43: {
+  s_n_llhttp__internal__n_error_46: {
     state->error = 0x9;
     state->reason = "Expected dot";
     state->error_pos = (const char*) p;
@@ -6381,7 +14790,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_44: {
+  s_n_llhttp__internal__n_error_47: {
     state->error = 0x9;
     state->reason = "Invalid major version";
     state->error_pos = (const char*) p;
@@ -6390,7 +14799,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_47: {
+  s_n_llhttp__internal__n_error_50: {
     state->error = 0x8;
     state->reason = "Expected HTTP/";
     state->error_pos = (const char*) p;
@@ -6415,7 +14824,7 @@ static llparse_state_t llhttp__internal__run(
     /* UNREACHABLE */;
     abort();
   }
-  s_n_llhttp__internal__n_error_45: {
+  s_n_llhttp__internal__n_error_48: {
     state->error = 0x8;
     state->reason = "Invalid word encountered";
     state->error_pos = (const char*) p;
@@ -6512,4 +14921,6 @@ int llhttp__internal_execute(llhttp__internal_t* state, const char* p, const cha
   }
   
   return 0;
-}
\ No newline at end of file
+}
+
+#endif  /* LLHTTP_STRICT_MODE */
index 2353ff6..366149f 100644 (file)
@@ -42,3 +42,4 @@ of this list.
    Masahiro Wakame
    YAMAMOTO Masaya
    KOBAYASHI Shuji
+   RIZAL Reckordp
index 6bababb..0b632f5 100644 (file)
@@ -9,7 +9,7 @@ things in mind before submitting your pull request:
 
 * Work on the latest possible state of **mruby/master**
 * Create a branch which is dedicated to your change
-* Test your changes before creating a pull request (```./minirake test```)
+* Test your changes before creating a pull request (```rake test```)
 * If possible write a test case which confirms your change
 * Don't mix several features or bug-fixes in one pull request
 * Create a meaningful commit message
@@ -33,9 +33,16 @@ mruby should be highly portable to other systems and compilers. For this it is
 recommended to keep your code as close as possible to the C99 standard
 (http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf).
 
-Although we target C99, Visual C++ is also an important target for mruby. For
-this reason a declaration of a local variable has to be at the beginning of a
-scope block.
+Although we target C99, we've heard some compilers in the embedded environment
+still requires declarations of local variables to be at the beginning of a
+scope. Until we confirm the situation has changed, we use the old-style
+variable declaration.
+
+Visual C++ is also an important target for mruby (supported version is 2013 or
+later). For this reason features that are not supported by Visual C++ may not
+be used (e.g. `%z` of `strftime()`).
+
+NOTE: Old GCC requires `-std=gnu99` option to enable C99 support.
 
 #### Reduce library dependencies to a minimum
 
diff --git a/third-party/mruby/Doxyfile b/third-party/mruby/Doxyfile
new file mode 100644 (file)
index 0000000..2550aac
--- /dev/null
@@ -0,0 +1,2408 @@
+# Doxyfile 1.8.13
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+DOXYFILE_ENCODING      = UTF-8
+PROJECT_NAME           = "mruby"
+PROJECT_NUMBER         = 2.1.2
+
+PROJECT_BRIEF          = "mruby is the lightweight implementation of the Ruby language"
+
+PROJECT_LOGO           = doc/mruby_logo_red_icon.png
+
+OUTPUT_DIRECTORY       = doc/capi
+
+USE_MDFILE_AS_MAINPAGE = README.md
+
+INPUT                  = README.md \
+                         src \
+                         include \
+                         include/mruby \
+                         mrblib \
+                         doc \
+                         doc/guides
+
+# Red for Ruby
+HTML_COLORSTYLE_HUE    = 359
+
+# The following expansions 
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = YES
+EXPAND_ONLY_PREDEF     = NO
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = NO
+
+# This tells doxygen to search the places that make sense
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = include include/mruby
+INCLUDE_FILE_PATTERNS  = *.h
+
+CLANG_ASSISTED_PARSING = NO
+CLANG_OPTIONS          = -I./include
+
+# This thing creates documentation elements for everything, even when its not documented. Its a little ugly to do it right now because huge swathes of code aren't documented.
+EXTRACT_ALL            = NO
+
+# Document MRB_INLINE functions
+EXTRACT_STATIC         = YES
+
+JAVADOC_AUTOBRIEF      = YES
+QT_AUTOBRIEF           = NO
+
+QUIET                  = YES
+WARN_IF_UNDOCUMENTED   = NO
+
+#===========================================================================
+# BELOW THIS LINE IS CRUFT GENERATED BY doxygen -g
+# If you edit anything below this, bring it up here so its easier to read.
+#===========================================================================
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 0.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS   = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR          = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.idl \
+                         *.ddl \
+                         *.odl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.cs \
+                         *.d \
+                         *.php \
+                         *.php4 \
+                         *.php5 \
+                         *.phtml \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.pyw \
+                         *.f90 \
+                         *.f95 \
+                         *.f03 \
+                         *.f08 \
+                         *.f \
+                         *.for \
+                         *.tcl \
+                         *.vhd \
+                         *.vhdl \
+                         *.ucf \
+                         *.qsf
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse-libclang=ON option for CMake.
+# The default value is: NO.
+
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: YES.
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
+# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
+# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      =
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE      =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
index ab54323..363428a 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 2019 mruby developers
+Copyright (c) 2020 mruby developers
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
index 4912f17..7f1a744 100644 (file)
@@ -1,8 +1,6 @@
 # mruby is using Rake (http://rake.rubyforge.org) as a build tool.
-# We provide a minimalistic version called minirake inside of our
-# codebase.
 
-RAKE = ruby ./minirake
+RAKE = rake
 
 all :
        $(RAKE)
index 3e71ef7..5bea9d4 100644 (file)
@@ -3,7 +3,7 @@
 ## What is mruby
 
 mruby is the lightweight implementation of the Ruby language complying to (part
-of) the [ISO standard][ISO-standard]. Its syntax is Ruby 1.9 compatible.
+of) the [ISO standard][ISO-standard]. Its syntax is Ruby 2.x compatible.
 
 mruby can be linked and embedded within your application.  We provide the
 interpreter program "mruby" and the interactive mruby shell "mirb" as examples.
@@ -17,7 +17,7 @@ of the Ministry of Economy, Trade and Industry of Japan.
 
 ## How to get mruby
 
-The stable version 2.0.1 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/2.0.1.zip](https://github.com/mruby/mruby/archive/2.0.1.zip)
+The stable version 2.1.2 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/2.1.2.zip](https://github.com/mruby/mruby/archive/2.1.2.zip)
 
 The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master)
 
@@ -30,36 +30,49 @@ You can also install and compile mruby using [ruby-install](https://github.com/p
 
 ## mruby home-page
 
-The URL of the mruby home-page is: [http://www.mruby.org](http://www.mruby.org).
+The URL of the mruby home-page is: https://mruby.org.
 
 ## Mailing list
 
-We don't have a mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby).
+We don't have a mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby/issues).
 
 ## How to compile and install (mruby and gems)
 
-See the [doc/guides/compile.md](doc/guides/compile.md) file.
+See the [compile.md](https://github.com/mruby/mruby/blob/master/doc/guides/compile.md) file.
 
 ## Running Tests
 
 To run the tests, execute the following from the project's root directory.
 
-    $ make test
+    $ rake test
 
-Or
+Note: `bison` bundled with MacOS is too old to compile `mruby`.
+Try `brew install bison` and follow the instuction shown to update
+the `$PATH` to compile `mruby`.
 
-    $ ruby ./minirake test
+## Building documentation
+
+There are two sets of documentation in mruby: the mruby API (generated by yard) and C API (Doxygen)
+
+To build both of them, simply go
+
+    rake doc
+
+You can also view them in your browser
+
+    rake view_api
+    rake view_capi
 
 ## How to customize mruby (mrbgems)
 
 mruby contains a package manager called *mrbgems*. To create extensions
 in C and/or Ruby you should create a *GEM*. For a documentation of how to
-use mrbgems consult the file [doc/guides/mrbgems.md](doc/guides/mrbgems.md). For example code of
-how to use mrbgems look into the folder *examples/mrbgems/*.
+use mrbgems consult the file [mrbgems.md](https://github.com/mruby/mruby/blob/master/doc/guides/mrbgems.md).
+For example code of how to use mrbgems look into the folder *examples/mrbgems/*.
 
 ## License
 
-mruby is released under the [MIT License](LICENSE).
+mruby is released under the [MIT License](https://github.com/mruby/mruby/blob/master/LICENSE).
 
 ## Note for License
 
@@ -88,5 +101,5 @@ file in your pull request.
 
 [ISO-standard]: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579
 [build-status-img]: https://travis-ci.org/mruby/mruby.svg?branch=master
-[contribution-guidelines]: CONTRIBUTING.md
+[contribution-guidelines]: https://github.com/mruby/mruby/blob/master/CONTRIBUTING.md
 [travis-ci]: https://travis-ci.org/mruby/mruby
index 5331532..4115d9e 100644 (file)
@@ -5,12 +5,13 @@ MRUBY_ROOT = File.dirname(File.expand_path(__FILE__))
 MRUBY_BUILD_HOST_IS_CYGWIN = RUBY_PLATFORM.include?('cygwin')
 MRUBY_BUILD_HOST_IS_OPENBSD = RUBY_PLATFORM.include?('openbsd')
 
+Rake.verbose(false) if Rake.verbose == Rake::DSL::DEFAULT
+
 $LOAD_PATH << File.join(MRUBY_ROOT, "lib")
 
 # load build systems
 require "mruby-core-ext"
 require "mruby/build"
-require "mruby/gem"
 
 # load configuration file
 MRUBY_CONFIG = (ENV['MRUBY_CONFIG'] && ENV['MRUBY_CONFIG'] != '') ? ENV['MRUBY_CONFIG'] : "#{MRUBY_ROOT}/build_config.rb"
@@ -31,12 +32,12 @@ load "#{MRUBY_ROOT}/tasks/libmruby.rake"
 load "#{MRUBY_ROOT}/tasks/benchmark.rake"
 
 load "#{MRUBY_ROOT}/tasks/gitlab.rake"
+load "#{MRUBY_ROOT}/tasks/doc.rake"
 
 def install_D(src, dst)
-  opts = { :verbose => $verbose }
-  FileUtils.rm_f dst, opts
-  FileUtils.mkdir_p File.dirname(dst), opts
-  FileUtils.cp src, dst, opts
+  rm_f dst
+  mkdir_p File.dirname(dst)
+  cp src, dst
 end
 
 ##############################
@@ -62,7 +63,7 @@ MRuby.each_target do |target|
     relative_from_root = gem.dir.relative_path_from(MRUBY_ROOT)
     current_build_dir = File.expand_path "#{build_dir}/#{relative_from_root}"
 
-    if current_build_dir !~ /^#{build_dir}/
+    if current_build_dir !~ /^#{Regexp.escape(build_dir)}/
       current_build_dir = "#{build_dir}/mrbgems/#{gem.name}"
     end
 
@@ -118,6 +119,7 @@ task :all => depfiles do
   MRuby.each_target do
     print_build_summary
   end
+  MRuby::Lockfile.write
 end
 
 desc "run all mruby tests"
@@ -143,26 +145,16 @@ end
 desc "clean all built and in-repo installed artifacts"
 task :clean do
   MRuby.each_target do |t|
-    FileUtils.rm_rf t.build_dir, { :verbose => $verbose }
+    rm_rf t.build_dir
   end
-  FileUtils.rm_f depfiles, { :verbose => $verbose }
+  rm_f depfiles
   puts "Cleaned up target build folder"
 end
 
 desc "clean everything!"
-task :deep_clean => ["clean"] do
+task :deep_clean => ["clean", "clean_doc"] do
   MRuby.each_target do |t|
-    FileUtils.rm_rf t.gem_clone_dir, { :verbose => $verbose }
+    rm_rf t.gem_clone_dir
   end
   puts "Cleaned up mrbgems build folder"
 end
-
-desc 'generate document'
-task :doc do
-  begin
-    sh "mrbdoc"
-  rescue
-    puts "ERROR: To generate documents, you should install yard-mruby gem."
-    puts "  $ gem install yard-mruby"
-  end
-end
index a91834c..e135383 100644 (file)
@@ -4,20 +4,23 @@ os: Visual Studio 2017
 
 shallow_clone: true
 
-
-cache:
-  - win_flex_bison
-
-
 environment:
   matrix:
     # Visual Studio 2017 64bit
     - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
 
+    # Visual Studio 2017 32bit
+    - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat
+      machine: x86
+
     # Visual Studio 2015 64bit
     - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
       machine: amd64
 
+    # Visual Studio 2015 32bit
+    - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
+      machine: x86
+
     # Visual Studio 2013 64bit
     - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat
       machine: amd64
@@ -30,13 +33,7 @@ init:
   - ruby --version
 
 
-install:
-  - if not exist win_flex_bison (
-      appveyor DownloadFile "https://github.com/lexxmark/winflexbison/releases/download/v.2.5.10/win_flex_bison-2.5.10.zip" &
-      7z x -y -owin_flex_bison win_flex_bison-2.5.10.zip
-    )
-
 build_script:
-  - set YACC=.\win_flex_bison\win_bison.exe
   - set MRUBY_CONFIG=appveyor_config.rb
+  - rake -m
   - rake -E $stdout.sync=true test
index 2555b2f..25745da 100644 (file)
@@ -1,14 +1,7 @@
-MRuby::Build.new('debug') do |conf|
-  toolchain :visualcpp
-  enable_debug
-
-  # include all core GEMs
-  conf.gembox 'full-core'
-  conf.compilers.each do |c|
-    c.defines += %w(MRB_GC_STRESS MRB_GC_FIXED_ARENA MRB_METHOD_CACHE)
-  end
-
-  build_mrbc_exec
+def setup_option(conf)
+  conf.cc.flags[0].delete("/Zi") unless ENV['CFLAGS']
+  conf.cxx.flags[0].delete("/Zi") unless ENV['CFLAGS'] || ENV['CXXFLAGS']
+  conf.linker.flags << "/DEBUG:NONE" unless ENV['LDFLAGS']
 end
 
 MRuby::Build.new('full-debug') do |conf|
@@ -17,7 +10,8 @@ MRuby::Build.new('full-debug') do |conf|
 
   # include all core GEMs
   conf.gembox 'full-core'
-  conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK)
+  conf.cc.defines += %w(MRB_GC_STRESS MRB_METHOD_CACHE MRB_ENABLE_DEBUG_HOOK)
+  setup_option(conf)
 
   conf.enable_test
 end
@@ -30,6 +24,7 @@ MRuby::Build.new do |conf|
   conf.compilers.each do |c|
     c.defines += %w(MRB_GC_FIXED_ARENA)
   end
+  setup_option(conf)
   conf.enable_bintest
   conf.enable_test
 end
@@ -41,6 +36,7 @@ MRuby::Build.new('cxx_abi') do |conf|
   conf.compilers.each do |c|
     c.defines += %w(MRB_GC_FIXED_ARENA)
   end
+  setup_option(conf)
   conf.enable_bintest
   conf.enable_test
 
index 751317c..254a28c 100644 (file)
@@ -18,9 +18,9 @@ MRuby::Build.new do |conf|
   # end
   # conf.gem 'examples/mrbgems/c_and_ruby_extension_example'
   # conf.gem :core => 'mruby-eval'
-  # conf.gem :mgem => 'mruby-io'
-  # conf.gem :github => 'iij/mruby-io'
-  # conf.gem :git => 'git@github.com:iij/mruby-io.git', :branch => 'master', :options => '-v'
+  # conf.gem :mgem => 'mruby-onig-regexp'
+  # conf.gem :github => 'mattn/mruby-onig-regexp'
+  # conf.gem :git => 'git@github.com:mattn/mruby-onig-regexp.git', :branch => 'master', :options => '-v'
 
   # include the default GEMs
   conf.gembox 'default'
@@ -30,9 +30,9 @@ MRuby::Build.new do |conf|
   #   cc.flags = [ENV['CFLAGS'] || %w()]
   #   cc.include_paths = ["#{root}/include"]
   #   cc.defines = %w()
-  #   cc.option_include_path = '-I%s'
+  #   cc.option_include_path = %q[-I"%s"]
   #   cc.option_define = '-D%s'
-  #   cc.compile_options = "%{flags} -MMD -o %{outfile} -c %{infile}"
+  #   cc.compile_options = %Q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"]
   # end
 
   # mrbc settings
@@ -50,25 +50,25 @@ MRuby::Build.new do |conf|
   #   linker.library_paths = []
   #   linker.option_library = '-l%s'
   #   linker.option_library_path = '-L%s'
-  #   linker.link_options = "%{flags} -o %{outfile} %{objs} %{libs}"
+  #   linker.link_options = "%{flags} -o "%{outfile}" %{objs} %{libs}"
   # end
 
   # Archiver settings
   # conf.archiver do |archiver|
   #   archiver.command = ENV['AR'] || 'ar'
-  #   archiver.archive_options = 'rs %{outfile} %{objs}'
+  #   archiver.archive_options = 'rs "%{outfile}" %{objs}'
   # end
 
   # Parser generator settings
   # conf.yacc do |yacc|
   #   yacc.command = ENV['YACC'] || 'bison'
-  #   yacc.compile_options = '-o %{outfile} %{infile}'
+  #   yacc.compile_options = %q[-o "%{outfile}" "%{infile}"]
   # end
 
   # gperf settings
   # conf.gperf do |gperf|
   #   gperf.command = 'gperf'
-  #   gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
+  #   gperf.compile_options = %q[-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" "%{infile}" > "%{outfile}"]
   # end
 
   # file extensions
index 2aaf6f1..d7937bb 100644 (file)
@@ -6,11 +6,15 @@ binaries.
 ## Prerequisites
 
 To compile mruby out of the source code you need the following tools:
-* C Compiler (i.e. ```gcc```)
-* Linker (i.e. ```gcc```)
-* Archive utility (i.e. ```ar```)
-* Parser generator (i.e. ```bison```)
-* Ruby 1.8 or 1.9 (i.e. ```ruby``` or ```jruby```)
+* C Compiler (e.g. `gcc` or `clang`)
+* Linker (e.g. `gcc` or `clang`)
+* Archive utility (e.g. `ar`)
+* Parser generator (e.g. `bison`)
+* Ruby 2.0 or later (e.g. `ruby` or `jruby`)
+
+Note that `bison` bundled with MacOS is too old to compile `mruby`.
+Try `brew install bison` and follow the instuction shown to update
+the `$PATH` to compile `mruby`.
 
 Optional:
 * GIT (to update mruby source and integrate mrbgems easier)
@@ -32,10 +36,10 @@ All tools necessary to compile mruby can be set or modified here. In case
 you want to maintain an additional *build_config.rb* you can define a
 customized path using the *$MRUBY_CONFIG* environment variable.
 
-To compile just call ```./minirake``` inside of the mruby source root. To
-generate and execute the test tools call ```./minirake test```. To clean
-all build files call ```./minirake clean```. To see full command line on
-build, call ```./minirake -v```.
+To compile just call `rake` inside of the mruby source root. To
+generate and execute the test tools call `rake test`. To clean
+all build files call `rake clean`. To see full command line on
+build, call `rake -v`.
 
 ## Build Configuration
 
@@ -79,7 +83,7 @@ toolchain :android
 ```
 
 Requires the custom standalone Android NDK and the toolchain path
-in ```ANDROID_STANDALONE_TOOLCHAIN```.
+in `ANDROID_STANDALONE_TOOLCHAIN`.
 
 ### Binaries
 
@@ -97,7 +101,7 @@ conf.gem "#{root}/mrbgems/mruby-bin-mirb"
 ### File Separator
 
 Some environments require a different file separator character. It is possible to
-set the character via ```conf.file_separator```.
+set the character via `conf.file_separator`.
 ```ruby
 conf.file_separator = '/'
 ```
@@ -119,7 +123,7 @@ end
 
 C Compiler has header searcher to detect installed library.
 
-If you need a include path of header file use ```search_header_path```:
+If you need a include path of header file use `search_header_path`:
 ```ruby
 # Searches ```iconv.h```.
 # If found it will return include path of the header file.
@@ -127,7 +131,7 @@ If you need a include path of header file use ```search_header_path```:
 fail 'iconv.h not found' unless conf.cc.search_header_path 'iconv.h'
 ```
 
-If you need a full file name of header file use ```search_header```:
+If you need a full file name of header file use `search_header`:
 ```ruby
 # Searches ```iconv.h```.
 # If found it will return full path of the header file.
@@ -136,11 +140,11 @@ iconv_h = conf.cc.search_header 'iconv.h'
 print "iconv.h found: #{iconv_h}\n"
 ```
 
-Header searcher uses compiler's ```include_paths``` by default.
+Header searcher uses compiler's `include_paths` by default.
 When you are using GCC toolchain (including clang toolchain since its base is gcc toolchain)
-it will use compiler specific include paths too. (For example ```/usr/local/include```, ```/usr/include```)
+it will use compiler specific include paths too. (For example `/usr/local/include`, `/usr/include`)
 
-If you need a special header search paths define a singleton method ```header_search_paths``` to C compiler:
+If you need a special header search paths define a singleton method `header_search_paths` to C compiler:
 ```ruby
 def conf.cc.header_search_paths
   ['/opt/local/include'] + include_paths
@@ -222,7 +226,7 @@ See doc/mrbgems/README.md for more option about mrbgems.
 
 Configuration Mrbtest build process.
 
-If you want mrbtest.a only, You should set ```conf.build_mrbtest_lib_only```
+If you want mrbtest.a only, You should set `conf.build_mrbtest_lib_only`
 ```ruby
 conf.build_mrbtest_lib_only
 ```
@@ -230,9 +234,9 @@ conf.build_mrbtest_lib_only
 ### Bintest
 
 Tests for mrbgem tools using CRuby.
-To have bintests place \*.rb scripts to ```bintest/``` directory of mrbgems.
-See ```mruby-bin-*/bintest/*.rb``` if you need examples.
-If you want a temporary files use `tempfile` module of CRuby instead of ```/tmp/```.
+To have bintests place \*.rb scripts to `bintest/` directory of mrbgems.
+See `mruby-bin-*/bintest/*.rb` if you need examples.
+If you want a temporary files use `tempfile` module of CRuby instead of `/tmp/`.
 
 You can enable it with following:
 ```ruby
@@ -247,8 +251,8 @@ correctly. To support mrbgems written in C++, mruby can be
 configured to use C++ exception.
 
 There are two levels of C++ exception handling. The one is
-```enable_cxx_exception``` that enables C++ exception, but
-uses C ABI. The other is ```enable_cxx_abi``` where all
+`enable_cxx_exception` that enables C++ exception, but
+uses C ABI. The other is `enable_cxx_abi` where all
 files are compiled by C++ compiler.
 
 When you mix C++ code, C++ exception would be enabled automatically.
@@ -266,7 +270,7 @@ C++ exception, add following:
 conf.disable_cxx_exception
 ```
 and you will get an error when you try to use C++ gem.
-Note that it must be called before ```enable_cxx_exception``` or ```gem``` method.
+Note that it must be called before `enable_cxx_exception` or `gem` method.
 
 ### Debugging mode
 
@@ -276,17 +280,17 @@ conf.enable_debug
 ```
 
 When debugging mode is enabled
-* Macro ```MRB_DEBUG``` would be defined.
-       * Which means ```mrb_assert()``` macro is enabled.
-* Debug information of irep would be generated by ```mrbc```.
-       * Because ```-g``` flag would be added to ```mrbc``` runner.
+* Macro `MRB_DEBUG` would be defined.
+       * Which means `mrb_assert()` macro is enabled.
+* Debug information of irep would be generated by `mrbc`.
+       * Because `-g` flag would be added to `mrbc` runner.
     * You can have better backtrace of mruby scripts with this.
 
 ## Cross-Compilation
 
 mruby can also be cross-compiled from one platform to another. To
 achieve this the *build_config.rb* needs to contain an instance of
-```MRuby::CrossBuild```. This instance defines the compilation
+`MRuby::CrossBuild`. This instance defines the compilation
 tools and flags for the target platform. An example could look
 like this:
 ```ruby
@@ -298,12 +302,12 @@ MRuby::CrossBuild.new('32bit') do |conf|
 end
 ```
 
-All configuration options of ```MRuby::Build``` can also be used
-in ```MRuby::CrossBuild```.
+All configuration options of `MRuby::Build` can also be used
+in `MRuby::CrossBuild`.
 
 ### Mrbtest in Cross-Compilation
 
-In cross compilation, you can run ```mrbtest``` on emulator if
+In cross compilation, you can run `mrbtest` on emulator if
 you have it by changing configuration of test runner.
 ```ruby
 conf.test_runner do |t|
@@ -350,15 +354,15 @@ in *build/host/src*)
 result will be stored in *build/host/src/y.tab.c*)
 * compile  *build/host/src/y.tab.c* to  *build/host/src/y.tab.o*
 * create *build/host/lib/libmruby_core.a* out of all object files (C only)
-* create ```build/host/bin/mrbc``` by compiling *tools/mrbc/mrbc.c* and
+* create `build/host/bin/mrbc` by compiling *tools/mrbc/mrbc.c* and
 linking with *build/host/lib/libmruby_core.a*
 * create *build/host/mrblib/mrblib.c* by compiling all \*.rb files
-under *mrblib* with ```build/host/bin/mrbc```
+under *mrblib* with `build/host/bin/mrbc`
 * compile *build/host/mrblib/mrblib.c* to *build/host/mrblib/mrblib.o*
 * create *build/host/lib/libmruby.a* out of all object files (C and Ruby)
-* create ```build/host/bin/mruby``` by compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and
+* create `build/host/bin/mruby` by compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and
 linking with *build/host/lib/libmruby.a*
-* create ```build/host/bin/mirb``` by compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and
+* create `build/host/bin/mirb` by compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and
 linking with *build/host/lib/libmruby.a*
 
 ```
@@ -427,15 +431,15 @@ in *build/i386/src*)
 result will be stored in *build/i386/src/y.tab.c*)
 * cross-compile *build/i386/src/y.tab.c* to *build/i386/src/y.tab.o*
 * create *build/i386/mrblib/mrblib.c* by compiling all \*.rb files
-under *mrblib* with the native ```build/host/bin/mrbc```
+under *mrblib* with the native `build/host/bin/mrbc`
 * cross-compile *build/host/mrblib/mrblib.c* to *build/host/mrblib/mrblib.o*
 * create *build/i386/lib/libmruby.a* out of all object files (C and Ruby)
-* create ```build/i386/bin/mruby``` by cross-compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and
+* create `build/i386/bin/mruby` by cross-compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and
 linking with *build/i386/lib/libmruby.a*
-* create ```build/i386/bin/mirb``` by cross-compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and
+* create `build/i386/bin/mirb` by cross-compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and
 linking with *build/i386/lib/libmruby.a*
 * create *build/i386/lib/libmruby_core.a* out of all object files (C only)
-* create ```build/i386/bin/mrbc``` by cross-compiling *tools/mrbc/mrbc.c* and
+* create `build/i386/bin/mrbc` by cross-compiling *tools/mrbc/mrbc.c* and
 linking with *build/i386/lib/libmruby_core.a*
 
 ```
@@ -463,7 +467,7 @@ linking with *build/i386/lib/libmruby_core.a*
 ### Minimal Library
 
 To build a minimal mruby library you need to use the Cross Compiling
-feature due to the reason that there are functions (i.e. stdio) which
+feature due to the reason that there are functions (e.g. stdio) which
 can't be disabled for the main build.
 
 ```ruby
@@ -477,12 +481,12 @@ end
 
 This configuration defines a cross compile build called 'Minimal' which
 is using the GCC and compiles for the host machine. It also disables
-all usages of stdio and doesn't compile any binaries (i.e. mrbc).
+all usages of stdio and doesn't compile any binaries (e.g. mrbc).
 
 ## Test Environment
 
 mruby's build process includes a test environment. In case you start the testing
-of mruby, a native binary called ```mrbtest``` will be generated and executed.
+of mruby, a native binary called `mrbtest` will be generated and executed.
 This binary contains all test cases which are defined under *test/t*. In case
 of a cross-compilation an additional cross-compiled *mrbtest* binary is
 generated. You can copy this binary and run on your target system.
index 81c0e9d..61c0418 100644 (file)
@@ -38,7 +38,7 @@ To confirm mrdb was installed properly, run mrdb with the `--version` option:
 
 ```bash
 $ mrdb --version
-mruby 2.0.1 (2019-4-4)
+mruby 2.1.2 (2020-08-06)
 ```
 
 ## 2.2 Basic Operation
index f957f8c..1e1a5af 100644 (file)
@@ -50,15 +50,17 @@ You can use mrbconfs with following ways:
 * When defined single precision floating point type(C type `float`) is used as `mrb_float`.
 * Else double precision floating point type(C type `double`) is used as `mrb_float`.
 
-`MRB_INT16`
-* When defined `int16_t` will be defined as `mrb_int`.
+`MRB_WITHOUT_FLOAT`
+* When defined removes floating point numbers from mruby.
+* It makes mruby easier to handle in "Microcontroller without FPU" and "Kernel Space".
+
+`MRB_INT32`
+* When defined, or `MRB_INT64` are not defined on 32-bit CPU mode, `mrb_int` will be defined as `int32_t`.
 * Conflicts with `MRB_INT64`.
 
 `MRB_INT64`
-* When defined `int64_t` will be defined as `mrb_int`.
-* Conflicts with `MRB_INT16`.
-* When `MRB_INT16` or `MRB_INT64` isn't defined `int`(most of the times 32-bit integer)
-will be defined as `mrb_int`.
+* When defined, or `MRB_INT32` are not defined on 64-bit CPU mode, `mrb_int` will be defined as `int64_t`.
+* Conflicts with `MRB_INT32`.
 
 ## Garbage collector configuration.
 
@@ -115,7 +117,7 @@ largest value of required alignment.
 
 `MRB_NAN_BOXING`
 * If defined represent `mrb_value` in boxed `double`.
-* Conflicts with `MRB_USE_FLOAT`.
+* Conflicts with `MRB_USE_FLOAT` and `MRB_WITHOUT_FLOAT`.
 
 `MRB_WORD_BOXING`
 * If defined represent `mrb_value` as a word.
@@ -126,6 +128,22 @@ largest value of required alignment.
 * Default value is `4`.
 * Specifies size of each segment in segment list.
 
+## Reduce heap memory configuration.
+
+`MRB_USE_LINK_TIME_RO_DATA_P`
+* Only available on ELF platforms.
+* If you specify the address of a read-only section when creating a symbol or string, that string will be used as it is.
+* Heap memory can be saved.
+* Uses `__ehdr_start` and `__init_array_start`.
+* It must be `__ehdr_start < data_addr < __init_array_start`.
+
+`MRB_USE_CUSTOM_RO_DATA_P`
+* Takes precedence over `MRB_USE_LINK_TIME_RO_DATA_P`.
+* Please try if `MRB_USE_LINK_TIME_RO_DATA_P` is not available.
+* The `mrb_ro_data_p()` function is implemented by the user in an arbitrary file.
+* The prototype declaration is `mrb_bool mrb_ro_data_p(const char *ptr)`.
+* Return `TRUE` if `ptr` is in read-only section, otherwise return `FALSE`.
+
 ## Other configuration.
 `MRB_UTF8_STRING`
 * Adds UTF-8 encoding support to character-oriented String instance methods.
@@ -144,3 +162,20 @@ largest value of required alignment.
 `MRB_STR_BUF_MIN_SIZE`
 * Default value is `128`.
 * Specifies initial capacity of `RString` created by `mrb_str_buf_new` function..
+
+`MRB_METHOD_CACHE`
+* Improve performance for method dispatch.
+
+`MRB_METHOD_CACHE_SIZE`
+* Default value is `128`.
+* Ignored if `MRB_METHOD_CACHE` is not defined.
+* Need to be the power of 2.
+
+`MRB_METHOD_T_STRUCT`
+* Use C struct to represent `mrb_method_t`
+* No `MRB_METHOD_T_STRUCT` requires highest 2 bits of function pointers to be zero
+* Define this macro on machines that use higher bits of pointers
+
+`MRB_ENABLE_ALL_SYMBOLS`
+* Make it available `Symbols.all_symbols` in `mrbgems/mruby-symbol-ext`
+* Increase heap memory usage.
index 0fcc936..ffbf17f 100644 (file)
@@ -37,11 +37,16 @@ conf.gem :mgem => 'mruby-yaml'
 conf.gem :mgem => 'yaml' # 'mruby-' prefix could be omitted
 ```
 
+For specifying commit hash to checkout use `:checksum_hash` option:
+```ruby
+conf.gem mgem: 'mruby-redis', checksum_hash: '3446d19fc4a3f9697b5ddbf2a904f301c42f2f4e'
+```
+
 If there is missing dependencies, mrbgem dependencies solver will reference
 mrbgem from core or mgem-list.
 
-To pull all gems from remote GIT repository on build, call ```./minirake -p```,
-or ```./minirake --pull-gems```.
+To pull all gems from remote GIT repository on build, call ```rake -p```,
+or ```rake --pull-gems```.
 
 NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version.
 
@@ -230,7 +235,7 @@ So it is recommended not to put GEM's local header files on include/.
 These exports are retroactive.
 For example: when B depends to C and A depends to B, A will get include paths exported by C.
 
-Exported include_paths are automatically appended to GEM local include_paths by Minirake.
+Exported include_paths are automatically appended to GEM local include_paths by rake.
 You can use `spec.export_include_paths` accessor if you want more complex build.
 
 
index 9b4ed9c..770daa7 100644 (file)
@@ -14,17 +14,17 @@ This document does not contain a complete list of limitations.
 Please help to improve it by submitting your findings.
 
 
-## ```1/2``` gives ```0.5```
+## `1/2` gives `0.5`
 
-Since mruby does not have ```Bignum```, bigger integers are represented
-by ```Float``` numbers. To enhance interoperability between ```Fixnum```
-and ```Float```, mruby provides ```Float#upto``` and other iterating
-methods for the ```Float``` class.  As a side effect, ```1/2``` gives ```0.5```
-not ```0```.
+Since mruby does not have `Bignum`, bigger integers are represented
+by `Float` numbers. To enhance interoperability between `Fixnum`
+and `Float`, mruby provides `Float#upto` and other iterating
+methods for the `Float` class.  As a side effect, `1/2` gives `0.5`
+not `0`.
 
-## ```Array``` passed to ```puts```
+## `Array` passed to `puts`
 
-Passing an Array to ```puts``` results in different output.
+Passing an Array to `puts` results in different output.
 
 ```ruby
 puts [1,2,3]
@@ -38,15 +38,15 @@ puts [1,2,3]
 3
 ```
 
-#### mruby [2.0.1 (2019-4-4)]
+#### mruby [2.1.2 (2020-08-06)]
 
 ```
 [1, 2, 3]
 ```
 
-## ```Kernel.raise``` in rescue clause
+## `Kernel.raise` in rescue clause
 
-```Kernel.raise``` without arguments does not raise the current exception within
+`Kernel.raise` without arguments does not raise the current exception within
 a rescue clause.
 
 ```ruby
@@ -59,21 +59,21 @@ end
 
 #### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)]
 
-```ZeroDivisionError``` is raised.
+`ZeroDivisionError` is raised.
 
-#### mruby [2.0.1 (2019-4-4)]
+#### mruby [2.1.2 (2020-08-06)]
 
 No exception is raised.
 
 ## Fiber execution can't cross C function boundary
 
-mruby's ```Fiber``` is implemented in a similar way to Lua's co-routine. This
+mruby's `Fiber` is implemented in a similar way to Lua's co-routine. This
 results in the consequence that you can't switch context within C functions.
-Only exception is ```mrb_fiber_yield``` at return.
+Only exception is `mrb_fiber_yield` at return.
 
-## ```Array``` does not support instance variables
+## `Array` does not support instance variables
 
-To reduce memory consumption ```Array``` does not support instance variables.
+To reduce memory consumption `Array` does not support instance variables.
 
 ```ruby
 class Liste < Array
@@ -87,16 +87,16 @@ p Liste.new "foobar"
 
 #### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)]
 
-``` [] ```
+` [] `
 
-#### mruby [2.0.1 (2019-4-4)]
+#### mruby [2.1.2 (2020-08-06)]
 
-```ArgumentError``` is raised.
+`ArgumentError` is raised.
 
 ## Method visibility
 
 For simplicity reasons no method visibility (public/private/protected) is
-supported.
+supported. Those methods are defined but they are dummy methods.
 
 ```ruby
 class VisibleTest
@@ -119,17 +119,53 @@ false
 true
 ```
 
-#### mruby [2.0.1 (2019-4-4)]
+#### mruby [2.1.2 (2020-08-06)]
 
 ```
 true
 true
 ```
 
-## defined?
+### Visibility Declaration
 
-The ```defined?``` keyword is considered too complex to be fully
-implemented. It is recommended to use ```const_defined?``` and
+The declaration form of following visibility methods are not implemented.
+
+* `public`
+* `private`
+* `protected`
+* `module_function`
+
+Especially, `module_function` method is not dummy, but no declaration form.
+
+```
+module TestModule
+  module_function
+  def test_func
+    p 'test_func called'
+  end
+
+  test_func
+end
+
+p 'ok'
+```
+
+#### Ruby [ruby 2.5.5p157 (2019-03-15 revision 67260)]
+
+```
+ok
+```
+
+#### mruby [2.1.2 (2020-08-06)]
+
+```
+test.rb:8: undefined method 'test_func' (NoMethodError)
+```
+
+## `defined?`
+
+The `defined?` keyword is considered too complex to be fully
+implemented. It is recommended to use `const_defined?` and
 other reflection methods instead.
 
 ```ruby
@@ -142,11 +178,11 @@ defined?(Foo)
 nil
 ```
 
-#### mruby [2.0.1 (2019-4-4)]
+#### mruby [2.1.2 (2020-08-06)]
 
-```NameError``` is raised.
+`NameError` is raised.
 
-## ```alias``` on global variables
+## `alias` on global variables
 
 Aliasing a global variable works in CRuby but is not part
 of the ISO standard.
@@ -157,9 +193,9 @@ alias $a $__a__
 
 #### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)]
 
-``` nil ```
+` nil `
 
-#### mruby [2.0.1 (2019-4-4)]
+#### mruby [2.1.2 (2020-08-06)]
 
 Syntax error
 
@@ -178,15 +214,15 @@ end
 
 #### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)]
 
-```ArgumentError``` is raised.
-The re-defined ```+``` operator does not accept any arguments.
+`ArgumentError` is raised.
+The re-defined `+` operator does not accept any arguments.
 
-#### mruby [2.0.1 (2019-4-4)]
+#### mruby [2.1.2 (2020-08-06)]
 
-``` 'ab' ```
+` 'ab' `
 Behavior of the operator wasn't changed.
 
-## Kernel#binding is not supported
+## `Kernel#binding` is not supported
 
 `Kernel#binding` method is not supported.
 
@@ -197,7 +233,7 @@ $ ruby -e 'puts Proc.new {}.binding'
 #<Binding:0x00000e9deabb9950>
 ```
 
-#### mruby [2.0.1 (2019-4-4)]
+#### mruby [2.1.2 (2020-08-06)]
 
 ```
 $ ./bin/mruby -e 'puts Proc.new {}.binding'
@@ -219,7 +255,7 @@ $ ruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)'
 [[{"a"=>1}], {:b=>2}]
 ```
 
-#### mruby [mruby 2.0.1]
+#### mruby [mruby 2.1.2]
 
 ```
 $ ./bin/mruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)'
@@ -238,7 +274,7 @@ Destructured arguments (`b` and `c` in above example) cannot be accessed
 from the default expression of optional arguments and keyword arguments,
 since actual assignment is done after the evaluation of those default
 expressions. Thus:
-    
+
 ```ruby
 def f(a,(b,c),d=b)
   p [a,b,c,d]
@@ -247,3 +283,17 @@ f(1,[2,3])
 ```
 
 CRuby gives `[1,2,3,nil]`. mruby raises `NoMethodError` for `b`.
+
+## `nil?` redefinition in conditional expressions
+
+Redefinition of `nil?` is ignored in conditional expressions.
+
+```ruby
+a = "a"
+def a.nil?
+  true
+end
+puts(a.nil? ? "truthy" : "falsy")
+```
+
+Ruby outputs `falsy`. mruby outputs `truthy`.
diff --git a/third-party/mruby/doc/mruby_logo_red_icon.png b/third-party/mruby/doc/mruby_logo_red_icon.png
new file mode 100644 (file)
index 0000000..9006c84
Binary files /dev/null and b/third-party/mruby/doc/mruby_logo_red_icon.png differ
index eab82a2..a79453e 100644 (file)
@@ -16,7 +16,6 @@ In the table.1 below, the second field describes the size (and
 sign) of operands.
 
 * B: 8bit
-* sB: signed 8bit
 * S: 16bit
 * sS: signed 16bit
 * W: 24bit
@@ -31,97 +30,111 @@ with `"`, either `OP_EXT1` or `OP_EXT2` or `OP_EXT2` can be prefixed.
 
 ## table.1 Instruction Table
 
-|Instruction Name |Operand type |Semantics        
-|-----------------|-------------|-----------------
-|OP_NOP           | -           |                 
-|OP_MOVE"         |BB           |R(a) = R(b)      
-|OP_LOADL"        |BB           |R(a) = Pool(b)   
-|OP_LOADI"        |BsB          |R(a) = mrb_int(b)
-|OP_LOADI_0'      |B            |R(a) = 0
-|OP_LOADI_1'      |B            |R(a) = 1
-|OP_LOADI_2'      |B            |R(a) = 2
-|OP_LOADI_3'      |B            |R(a) = 3
-|OP_LOADSYM"      |BB           |R(a) = Syms(b)
-|OP_LOADNIL'      |B            |R(a) = nil
-|OP_LOADSELF'     |B            |R(a) = self
-|OP_LOADT'        |B            |R(a) = true
-|OP_LOADF'        |B            |R(a) = false
-|OP_GETGV"        |BB           |R(a) = getglobal(Syms(b))
-|OP_SETGV"        |BB           |setglobal(Syms(b), R(a))
-|OP_GETSV"        |BB           |R(a) = Special[b]
-|OP_SETSV"        |BB           |Special[b] = R(a)
-|OP_GETIV"        |BB           |R(a) = ivget(Syms(b))
-|OP_SETIV"        |BB           |ivset(Syms(b),R(a))
-|OP_GETCV"        |BB           |R(a) = cvget(Syms(b))
-|OP_SETCV"        |BB           |cvset(Syms(b),R(a))
-|OP_GETCONST"     |BB           |R(a) = constget(Syms(b))
-|OP_SETCONST"     |BB           |constset(Syms(b),R(a))
-|OP_GETMCNST"     |BB           |R(a) = R(a)::Syms(b)
-|OP_SETMCNST"     |BB           |R(a+1)::Syms(b) = R(a)
-|OP_GETUPVAR'     |BBB          |R(a) = uvget(b,c)
-|OP_SETUPVAR'     |BBB          |uvset(b,c,R(a))
-|OP_JMP           |S            |pc+=a
-|OP_JMPIF'        |SB           |if R(b) pc+=a
-|OP_JMPNOT'       |SB           |if !R(b) pc+=a
-|OP_ONERR         |sS           |rescue_push(pc+a)
-|OP_EXCEPT'       |B            |R(a) = exc
-|OP_RESCUE"       |BB           |R(b) = R(a).isa?(R(b))
-|OP_POPERR        |B            |a.times{rescue_pop()}
-|OP_RAISE'        |B            |raise(R(a))
-|OP_EPUSH'        |B            |ensure_push(SEQ[a])
-|OP_EPOP          |B            |A.times{ensure_pop().call}
-|OP_SENDV"        |BB           |R(a) = call(R(a),Syms(b),*R(a+1))
-|OP_SENDVB"       |BB           |R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2))
-|OP_SEND"         |BBB          |R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c))
-|OP_SENDB"        |BBB          |R(a) = call(R(a),Syms(Bx),R(a+1),...,R(a+c),&R(a+c+1))
-|OP_CALL'         |B            |R(a) = self.call(frame.argc, frame.argv)
-|OP_SUPER'        |BB           |R(a) = super(R(a+1),... ,R(a+b+1))
-|OP_ARGARY'       |BS           |R(a) = argument array (16=5:1:5:1:4)
-|OP_ENTER         |W            |arg setup according to flags (23=5:5:1:5:5:1:1)
-|OP_KARG"         |BB           |R(a) = kdict[Syms(Bx)]                          # todo
-|OP_KARG2"        |BB           |R(a) = kdict[Syms(Bx)]; kdict.rm(Syms(b))       # todo
-|OP_RETURN'       |B            |return R(a) (normal)
-|OP_RETURN_BLK'   |B            |return R(a) (in-block return)
-|OP_BREAK'        |B            |break R(a)
-|OP_BLKPUSH'      |BS           |R(a) = block (16=5:1:5:1:4)
-|OP_ADD"          |BB           |R(a) = R(a)+R(a+1)
-|OP_ADDI"         |BBB          |R(a) = R(a)+mrb_int(c)
-|OP_SUB"          |BB           |R(a) = R(a)-R(a+1)
-|OP_SUBI"         |BB           |R(a) = R(a)-C
-|OP_MUL"          |BB           |R(a) = R(a)*R(a+1)
-|OP_DIV"          |BB           |R(a) = R(a)/R(a+1)
-|OP_EQ"           |BB           |R(a) = R(a)==R(a+1)
-|OP_LT"           |BB           |R(a) = R(a)<R(a+1)
-|OP_LE"           |BB           |R(a) = R(a)<=R(a+1)
-|OP_GT"           |BB           |R(a) = R(a)>R(a+1)
-|OP_GE"           |BB           |R(a) = R(a)>=R(a+1)
-|OP_ARRAY'        |BB           |R(a) = ary_new(R(a),R(a+1)..R(a+b))
-|OP_ARRAY2"       |BB           |R(a) = ary_new(R(b),R(b+1)..R(b+c))
-|OP_ARYCAT'       |B            |ary_cat(R(a),R(a+1))
-|OP_ARYPUSH'      |B            |ary_push(R(a),R(a+1))
-|OP_AREF'         |BB           |R(a) = R(a)[b]
-|OP_ASET'         |BB           |R(a)[b] = R(a+1)
-|OP_APOST'        |BB           |*R(a),R(A+1)..R(A+C) = R(a)[B..]
-|OP_STRING"       |BB           |R(a) = str_dup(Lit(b))
-|OP_STRCAT'       |B            |str_cat(R(a),R(a+1))
-|OP_HASH'         |BB           |R(a) = hash_new(R(a),R(a+1)..R(a+b))
-|OP_HASHADD'      |BB           |R(a) = hash_push(R(a),R(a+1)..R(a+b))
-|OP_LAMBDA"       |BB           |R(a) = lambda(SEQ[b],OP_L_LAMBDA)
-|OP_BLOCK"        |BB           |R(a) = lambda(SEQ[b],OP_L_BLOCK)
-|OP_METHOD"       |BB           |R(a) = lambda(SEQ[b],OP_L_METHOD)
-|OP_RANGE_INC'    |B            |R(a) = range_new(R(a),R(a+1),FALSE)
-|OP_RANGE_EXC'    |B            |R(a) = range_new(R(a),R(a+1),TRUE)
-|OP_OCLASS'       |B            |R(a) = ::Object
-|OP_CLASS"        |BB           |R(a) = newclass(R(a),Syms(b),R(a+1))
-|OP_MODULE"       |BB           |R(a) = newmodule(R(a),Syms(b))
-|OP_EXEC"         |BB           |R(a) = blockexec(R(a),SEQ[b])
-|OP_DEF"          |BB           |R(a).newmethod(Syms(b),R(a+1))
-|OP_ALIAS'        |B            |alias_method(R(a),R(a+1),R(a+2))
-|OP_UNDEF"        |BB           |undef_method(R(a),Syms(b))
-|OP_SCLASS'       |B            |R(a) = R(a).singleton_class
-|OP_TCLASS'       |B            |R(a) = target_class
-|OP_ERR'          |B            |raise(RuntimeError, Lit(Bx))
-|OP_EXT1          |-            |make 1st operand 16bit
-|OP_EXT2          |-            |make 2nd operand 16bit
-|OP_EXT3          |-            |make 1st and 2nd operands 16bit
-|OP_STOP          |-            |stop VM
+| Instruction Name | Operand type | Semantics                                              |
+|------------------|--------------|--------------------------------------------------------|
+| OP_NOP           | -            | no operation                                           |
+| OP_MOVE"         | BB           | R(a) = R(b)                                            |
+| OP_LOADL"        | BB           | R(a) = Pool(b)                                         |
+| OP_LOADI"        | BB           | R(a) = mrb_int(b)                                      |
+| OP_LOADINEG"     | BB           | R(a) = mrb_int(-b)                                     |
+| OP_LOADI__1'     | B            | R(a) = mrb_int(-1)                                     |
+| OP_LOADI_0'      | B            | R(a) = mrb_int(0)                                      |
+| OP_LOADI_1'      | B            | R(a) = mrb_int(1)                                      |
+| OP_LOADI_2'      | B            | R(a) = mrb_int(2)                                      |
+| OP_LOADI_3'      | B            | R(a) = mrb_int(3)                                      |
+| OP_LOADI_4'      | B            | R(a) = mrb_int(4)                                      |
+| OP_LOADI_5'      | B            | R(a) = mrb_int(5)                                      |
+| OP_LOADI_6'      | B            | R(a) = mrb_int(6)                                      |
+| OP_LOADI_7'      | B            | R(a) = mrb_int(7)                                      |
+| OP_LOADI16'      | BsS          | R(a) = mrb_int(b)                                      |
+| OP_LOADSYM"      | BB           | R(a) = Syms(b)                                         |
+| OP_LOADNIL'      | B            | R(a) = nil                                             |
+| OP_LOADSELF'     | B            | R(a) = self                                            |
+| OP_LOADT'        | B            | R(a) = true                                            |
+| OP_LOADF'        | B            | R(a) = false                                           |
+| OP_GETGV"        | BB           | R(a) = getglobal(Syms(b))                              |
+| OP_SETGV"        | BB           | setglobal(Syms(b), R(a))                               |
+| OP_GETSV"        | BB           | R(a) = Special[Syms(b)]                                |
+| OP_SETSV"        | BB           | Special[Syms(b)] = R(a)                                |
+| OP_GETIV"        | BB           | R(a) = ivget(Syms(b))                                  |
+| OP_SETIV"        | BB           | ivset(Syms(b),R(a))                                    |
+| OP_GETCV"        | BB           | R(a) = cvget(Syms(b))                                  |
+| OP_SETCV"        | BB           | cvset(Syms(b),R(a))                                    |
+| OP_GETCONST"     | BB           | R(a) = constget(Syms(b))                               |
+| OP_SETCONST"     | BB           | constset(Syms(b),R(a))                                 |
+| OP_GETMCNST"     | BB           | R(a) = R(a)::Syms(b)                                   |
+| OP_SETMCNST"     | BB           | R(a+1)::Syms(b) = R(a)                                 |
+| OP_GETUPVAR"     | BBB          | R(a) = uvget(b,c)                                      |
+| OP_SETUPVAR"     | BBB          | uvset(b,c,R(a))                                        |
+| OP_JMP           | S            | pc=a                                                   |
+| OP_JMPIF'        | BS           | if R(a) pc=b                                           |
+| OP_JMPNOT'       | BS           | if !R(a) pc=b                                          |
+| OP_JMPNIL'       | BS           | if R(a)==nil pc=b                                      |
+| OP_ONERR         | S            | rescue_push(a)                                         |
+| OP_EXCEPT'       | B            | R(a) = exc                                             |
+| OP_RESCUE"       | BB           | R(b) = R(a).isa?(R(b))                                 |
+| OP_POPERR'       | B            | a.times{rescue_pop()}                                  |
+| OP_RAISE'        | B            | raise(R(a))                                            |
+| OP_EPUSH'        | B            | ensure_push(SEQ[a])                                    |
+| OP_EPOP'         | B            | A.times{ensure_pop().call}                             |
+| OP_SENDV"        | BB           | R(a) = call(R(a),Syms(b),*R(a+1))                      |
+| OP_SENDVB"       | BB           | R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2))              |
+| OP_SEND"         | BBB          | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c))            |
+| OP_SENDB"        | BBB          | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1))  |
+| OP_CALL          | -            | R(0) = self.call(frame.argc, frame.argv)               |
+| OP_SUPER"        | BB           | R(a) = super(R(a+1),... ,R(a+b+1))                     |
+| OP_ARGARY'       | BS           | R(a) = argument array (16=5:1:5:1:4)                   |
+| OP_ENTER         | W            | arg setup according to flags (23=5:5:1:5:5:1:1)        |
+| OP_KEY_P"        | BB           | R(a) = kdict.key?(Syms(b))                             |
+| OP_KEYEND        | -            | raise unless kdict.empty?                              |
+| OP_KARG"         | BB           | R(a) = kdict[Syms(b)]; kdict.delete(Syms(b))           |
+| OP_RETURN'       | B            | return R(a) (normal)                                   |
+| OP_RETURN_BLK'   | B            | return R(a) (in-block return)                          |
+| OP_BREAK'        | B            | break R(a)                                             |
+| OP_BLKPUSH'      | BS           | R(a) = block (16=5:1:5:1:4)                            |
+| OP_ADD'          | B            | R(a) = R(a)+R(a+1)                                     |
+| OP_ADDI"         | BB           | R(a) = R(a)+mrb_int(b)                                 |
+| OP_SUB'          | B            | R(a) = R(a)-R(a+1)                                     |
+| OP_SUBI"         | BB           | R(a) = R(a)-mrb_int(b)                                 |
+| OP_MUL'          | B            | R(a) = R(a)*R(a+1)                                     |
+| OP_DIV'          | B            | R(a) = R(a)/R(a+1)                                     |
+| OP_EQ'           | B            | R(a) = R(a)==R(a+1)                                    |
+| OP_LT'           | B            | R(a) = R(a)<R(a+1)                                     |
+| OP_LE'           | B            | R(a) = R(a)<=R(a+1)                                    |
+| OP_GT'           | B            | R(a) = R(a)>R(a+1)                                     |
+| OP_GE'           | B            | R(a) = R(a)>=R(a+1)                                    |
+| OP_ARRAY"        | BB           | R(a) = ary_new(R(a),R(a+1)..R(a+b))                    |
+| OP_ARRAY2"       | BBB          | R(a) = ary_new(R(b),R(b+1)..R(b+c))                    |
+| OP_ARYCAT'       | B            | ary_cat(R(a),R(a+1))                                   |
+| OP_ARYPUSH'      | B            | ary_push(R(a),R(a+1))                                  |
+| OP_ARYDUP'       | B            | R(a) = ary_dup(R(a))                                   |
+| OP_AREF"         | BBB          | R(a) = R(b)[c]                                         |
+| OP_ASET"         | BBB          | R(a)[c] = R(b)                                         |
+| OP_APOST"        | BBB          | *R(a),R(a+1)..R(a+c) = R(a)[b..]                       |
+| OP_INTERN'       | B            | R(a) = intern(R(a))                                    |
+| OP_STRING"       | BB           | R(a) = str_dup(Lit(b))                                 |
+| OP_STRCAT'       | B            | str_cat(R(a),R(a+1))                                   |
+| OP_HASH"         | BB           | R(a) = hash_new(R(a),R(a+1)..R(a+b))                   |
+| OP_HASHADD"      | BB           | R(a) = hash_push(R(a),R(a+1)..R(a+b))                  |
+| OP_HASHCAT'      | B            | R(a) = hash_cat(R(a),R(a+1))                           |
+| OP_LAMBDA"       | BB           | R(a) = lambda(SEQ[b],OP_L_LAMBDA)                      |
+| OP_BLOCK"        | BB           | R(a) = lambda(SEQ[b],OP_L_BLOCK)                       |
+| OP_METHOD"       | BB           | R(a) = lambda(SEQ[b],OP_L_METHOD)                      |
+| OP_RANGE_INC'    | B            | R(a) = range_new(R(a),R(a+1),FALSE)                    |
+| OP_RANGE_EXC'    | B            | R(a) = range_new(R(a),R(a+1),TRUE)                     |
+| OP_OCLASS'       | B            | R(a) = ::Object                                        |
+| OP_CLASS"        | BB           | R(a) = newclass(R(a),Syms(b),R(a+1))                   |
+| OP_MODULE"       | BB           | R(a) = newmodule(R(a),Syms(b))                         |
+| OP_EXEC"         | BB           | R(a) = blockexec(R(a),SEQ[b])                          |
+| OP_DEF"          | BB           | R(a).newmethod(Syms(b),R(a+1))                         |
+| OP_ALIAS"        | BB           | alias_method(target_class,Syms(a),Syms(b))             |
+| OP_UNDEF'        | B            | undef_method(target_class,Syms(a))                     |
+| OP_SCLASS'       | B            | R(a) = R(a).singleton_class                            |
+| OP_TCLASS'       | B            | R(a) = target_class                                    |
+| OP_DEBUG"        | BBB          | print a,b,c                                            |
+| OP_ERR'          | B            | raise(LocalJumpError, Lit(a))                          |
+| OP_EXT1          | -            | make 1st operand 16bit                                 |
+| OP_EXT2          | -            | make 2nd operand 16bit                                 |
+| OP_EXT3          | -            | make 1st and 2nd operands 16bit                        |
+| OP_STOP          | -            | stop VM                                                |
+|------------------|--------------|--------------------------------------------------------|
index 527aaa4..09646a7 100644 (file)
@@ -42,7 +42,7 @@ MRuby::CrossBuild.new("ArduinoDue") do |conf|
     cc.flags = %w(-g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500
                 -Dprintf=iprintf -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=156 -DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM
                 -D__SAM3X8E__ -mthumb -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Due")
-    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
 
     #configuration for low memory environment
     cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
@@ -64,7 +64,7 @@ MRuby::CrossBuild.new("ArduinoDue") do |conf|
 
   conf.archiver do |archiver|
     archiver.command = "#{BIN_PATH}/arm-none-eabi-ar"
-    archiver.archive_options = 'rcs %{outfile} %{objs}'
+    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
   end
 
   #no executables
index 8fa3aa0..a22f9cf 100644 (file)
@@ -32,7 +32,7 @@ MRuby::CrossBuild.new('core2-32-poky-linux') do |conf|
     cc.flags = %w(-m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -mstackrealign -fno-omit-frame-pointer)
     cc.flags << %w(-O2 -pipe -g -feliminate-unused-debug-types)
     cc.flags << "--sysroot=#{POKY_EDISON_SYSROOT}"
-    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
     cc.defines = %w(ENABLE_READLINE)
   end
 
@@ -47,7 +47,7 @@ MRuby::CrossBuild.new('core2-32-poky-linux') do |conf|
 
   conf.archiver do |archiver|
     archiver.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-ar"
-    archiver.archive_options = 'rcs %{outfile} %{objs}'
+    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
   end
 
   conf.linker do |linker|
index 42f800d..42f39c4 100644 (file)
@@ -39,7 +39,7 @@ MRuby::CrossBuild.new("Galileo") do |conf|
     cc.flags = %w(-m32 -march=i586 -c -g -Os -w
               -ffunction-sections -fdata-sections -MMD -DARDUINO=153)
     cc.flags << "--sysroot=#{GALILEO_SYSROOT}"
-    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
   end
 
   conf.cxx do |cxx|
@@ -54,7 +54,7 @@ MRuby::CrossBuild.new("Galileo") do |conf|
 
   conf.archiver do |archiver|
     archiver.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-ar"
-    archiver.archive_options = 'rcs %{outfile} %{objs}'
+    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
   end
 
   conf.linker do |linker|
index fd17eae..8b1bbb4 100644 (file)
@@ -27,7 +27,7 @@ MRuby::CrossBuild.new("RX630") do |conf|
   conf.cc do |cc|
     cc.command = "#{BIN_PATH}/rx-elf-gcc"
     cc.flags = "-Wall -g -O2 -flto -mcpu=rx600 -m64bit-doubles"
-    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
 
     #configuration for low memory environment
     cc.defines << %w(MRB_USE_FLOAT)
@@ -53,7 +53,7 @@ MRuby::CrossBuild.new("RX630") do |conf|
 
   conf.archiver do |archiver|
     archiver.command = "#{BIN_PATH}/rx-elf-ar"
-    archiver.archive_options = 'rcs %{outfile} %{objs}'
+    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
   end
 
   #no executables
index 951f714..8617d8d 100644 (file)
@@ -39,7 +39,7 @@ MRuby::CrossBuild.new("chipKITMax32") do |conf|
     cc.flags = %w(-O2 -mno-smart-io -w -ffunction-sections -fdata-sections -g -mdebugger -Wcast-align
                 -fno-short-double -mprocessor=32MX795F512L -DF_CPU=80000000L -DARDUINO=23 -D_BOARD_MEGA_
                 -DMPIDEVER=0x01000202 -DMPIDE=23)
-    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
 
     #configuration for low memory environment
     cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
@@ -60,7 +60,7 @@ MRuby::CrossBuild.new("chipKITMax32") do |conf|
 
   conf.archiver do |archiver|
     archiver.command = "#{PIC32_PATH}/compiler/pic32-tools/bin/pic32-ar"
-    archiver.archive_options = 'rcs %{outfile} %{objs}'
+    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
   end
 
   #no executables
diff --git a/third-party/mruby/examples/targets/build_config_dreamcast_shelf.rb b/third-party/mruby/examples/targets/build_config_dreamcast_shelf.rb
new file mode 100644 (file)
index 0000000..85b2ff2
--- /dev/null
@@ -0,0 +1,108 @@
+MRuby::Build.new do |conf|
+  # Gets set by the VS command prompts
+  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+    toolchain :visualcpp
+  else
+    toolchain :gcc
+  end
+
+  enable_debug
+
+  # Include the default GEMs
+  conf.gembox 'default'
+end
+
+# Cross Compiling configuration for the Sega Dreamcast
+# This configuration requires KallistiOS (KOS)
+# https://dreamcast.wiki
+#
+# Tested on GNU/Linux, MinGW-w64/MSYS2, Cygwin, macOS and MinGW/MSYS (see below)
+#
+MRuby::CrossBuild.new("dreamcast") do |conf|
+  toolchain :gcc
+
+  # Support for DreamSDK (based on MinGW/MSYS)
+  # To compile mruby with DreamSDK, RubyInstaller for Windows should be installed
+  DREAMSDK_HOME = ENV["DREAMSDK_HOME"]
+  MSYS_ROOT = !(DREAMSDK_HOME.nil? || DREAMSDK_HOME.empty?) ? "#{DREAMSDK_HOME}/msys/1.0" : ""
+  # Setting paths
+  DREAMCAST_PATH = "#{MSYS_ROOT}/opt/toolchains/dc"
+  KOS_PATH = "#{DREAMCAST_PATH}/kos"
+  BIN_PATH = "#{DREAMCAST_PATH}/sh-elf/bin"
+
+  # C compiler
+  # Flags were extracted from KallistiOS environment files
+  conf.cc do |cc|
+    cc.command = "#{BIN_PATH}/sh-elf-gcc"      
+    cc.include_paths << ["#{KOS_PATH}/include", "#{KOS_PATH}/kernel/arch/dreamcast/include", "#{KOS_PATH}/addons/include", "#{KOS_PATH}/../kos-ports/include"]
+    cc.flags << ["-O2", "-fomit-frame-pointer", "-ml", "-m4-single-only", "-ffunction-sections", "-fdata-sections", "-Wall", "-g", "-fno-builtin", "-ml", "-m4-single-only", "-Wl,-Ttext=0x8c010000", "-Wl,--gc-sections", "-T#{KOS_PATH}/utils/ldscripts/shlelf.xc", "-nodefaultlibs"]
+    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
+    cc.defines << %w(_arch_dreamcast)
+    cc.defines << %w(_arch_sub_pristine)
+  end
+
+  # C++ compiler
+  conf.cxx do |cxx|
+    cxx.command = conf.cc.command.dup
+    cxx.include_paths = conf.cc.include_paths.dup
+    cxx.flags = conf.cc.flags.dup
+    cxx.flags << %w(-fno-rtti -fno-exceptions)
+    cxx.defines = conf.cc.defines.dup
+    cxx.compile_options = conf.cc.compile_options.dup
+  end
+  # Linker
+  # There is an issue when making the mruby library with KallistiOS:
+  # 'newlib_kill.o' and 'newlib_getpid.o' aren't found so they are explicitly 
+  # specified here at least for now.
+  conf.linker do |linker|
+    linker.command="#{BIN_PATH}/sh-elf-gcc"
+    linker.flags << ["#{MSYS_ROOT}/opt/toolchains/dc/kos/kernel/build/newlib_kill.o", "#{MSYS_ROOT}/opt/toolchains/dc/kos/kernel/build/newlib_getpid.o", "-Wl,--start-group -lkallisti -lc -lgcc -Wl,--end-group"]
+    linker.library_paths << ["#{KOS_PATH}/lib/dreamcast", "#{KOS_PATH}/addons/lib/dreamcast", "#{KOS_PATH}/../kos-ports/lib"]
+  end  
+
+  # Archiver
+  conf.archiver do |archiver|
+    archiver.command = "#{BIN_PATH}/sh-elf-ar"
+    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
+  end
+
+  # No executables
+  conf.bins = []
+
+  # Do not build executable test
+  conf.build_mrbtest_lib_only
+
+  # Disable C++ exception
+  conf.disable_cxx_exception
+  
+  # Gems from core
+  # removing mruby-io
+  conf.gem :core => "mruby-metaprog"
+  conf.gem :core => "mruby-pack"
+  conf.gem :core => "mruby-sprintf"
+  conf.gem :core => "mruby-print"
+  conf.gem :core => "mruby-math"
+  conf.gem :core => "mruby-time"
+  conf.gem :core => "mruby-struct"
+  conf.gem :core => "mruby-compar-ext"
+  conf.gem :core => "mruby-enum-ext"
+  conf.gem :core => "mruby-string-ext"
+  conf.gem :core => "mruby-numeric-ext"
+  conf.gem :core => "mruby-array-ext"
+  conf.gem :core => "mruby-hash-ext"
+  conf.gem :core => "mruby-range-ext"
+  conf.gem :core => "mruby-proc-ext"
+  conf.gem :core => "mruby-symbol-ext"
+  conf.gem :core => "mruby-random"
+  conf.gem :core => "mruby-object-ext"
+  conf.gem :core => "mruby-objectspace"
+  conf.gem :core => "mruby-fiber"
+  conf.gem :core => "mruby-enumerator"
+  conf.gem :core => "mruby-enum-lazy"
+  conf.gem :core => "mruby-toplevel-ext"
+  conf.gem :core => "mruby-kernel-ext"
+  conf.gem :core => "mruby-class-ext"
+  conf.gem :core => "mruby-compiler"
+end
index 08e69d3..2b1adb2 100644 (file)
 /* size of the method cache (need to be the power of 2) */
 //#define MRB_METHOD_CACHE_SIZE (1<<7)
 
-/* add -DMRB_METHOD_TABLE_INLINE to reduce the size of method table */
-/* MRB_METHOD_TABLE_INLINE requires LSB of function pointers to be zero */
-/* you might need to specify --falign-functions=n (where n>1) */
-//#define MRB_METHOD_TABLE_INLINE
+/* add -DMRB_METHOD_T_STRUCT on machines that use higher bits of pointers */
+/* no MRB_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */
+#ifndef MRB_METHOD_T_STRUCT
+  // can't use highest 2 bits of function pointers at least on 32bit
+  // Windows and 32bit Linux.
+# ifdef MRB_32BIT
+#   define MRB_METHOD_T_STRUCT
+# endif
+#endif
 
-/* add -DMRB_INT16 to use 16bit integer for mrb_int; conflict with MRB_INT64 */
-//#define MRB_INT16
+/* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT64;
+   Default for 32-bit CPU mode. */
+//#define MRB_INT32
 
-/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT16 */
+/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT32;
+   Default for 64-bit CPU mode. */
 //#define MRB_INT64
 
 /* if no specific integer type is chosen */
-#if !defined(MRB_INT16) && !defined(MRB_INT32) && !defined(MRB_INT64)
+#if !defined(MRB_INT32) && !defined(MRB_INT64)
 # if defined(MRB_64BIT) && !defined(MRB_NAN_BOXING)
 /* Use 64bit integers on 64bit architecture (without MRB_NAN_BOXING) */
 #  define MRB_INT64
 /* number of object per heap page */
 //#define MRB_HEAP_PAGE_SIZE 1024
 
-/* if _etext and _edata available, mruby can reduce memory used by symbols */
-//#define MRB_USE_ETEXT_EDATA
+/* if __ehdr_start is available, mruby can reduce memory used by symbols */
+//#define MRB_USE_LINK_TIME_RO_DATA_P
 
-/* do not use __init_array_start to determine readonly data section;
-   effective only when MRB_USE_ETEXT_EDATA is defined */
-//#define MRB_NO_INIT_ARRAY_START
+/* if MRB_USE_LINK_TIME_RO_DATA_P does not work,
+   you can try mrb_ro_data_p() that you have implemented yourself in any file;
+   prototype is `mrb_bool mrb_ro_data_p(const char *ptr)` */
+//#define MRB_USE_CUSTOM_RO_DATA_P
 
 /* turn off generational GC by default */
 //#define MRB_GC_TURN_OFF_GENERATIONAL
 # define TRUE 1
 #endif
 
+/*
+** mruby tuning profiles
+**/
+
+/* A profile for micro controllers */
+#if defined(MRB_CONSTRAINED_BASELINE_PROFILE)
+# ifndef KHASH_DEFAULT_SIZE
+#  define KHASH_DEFAULT_SIZE 16
+# endif
+
+# ifndef MRB_STR_BUF_MIN_SIZE
+#  define MRB_STR_BUF_MIN_SIZE 32
+# endif
+
+# ifndef MRB_HEAP_PAGE_SIZE
+#  define MRB_HEAP_PAGE_SIZE 256
+# endif
+
+/* A profile for default mruby */
+#elif defined(MRB_BASELINE_PROFILE)
+
+/* A profile for desktop computers or workstations; rich memory! */
+#elif defined(MRB_MAIN_PROFILE)
+# ifndef MRB_METHOD_CACHE
+#  define MRB_METHOD_CACHE
+# endif
+
+# ifndef MRB_METHOD_CACHE_SIZE
+#  define MRB_METHOD_CACHE_SIZE (1<<10)
+# endif
+
+# ifndef MRB_IV_SEGMENT_SIZE
+#  define MRB_IV_SEGMENT_SIZE 32
+# endif
+
+# ifndef MRB_HEAP_PAGE_SIZE
+#  define MRB_HEAP_PAGE_SIZE 4096
+# endif
+
+/* A profile for server; mruby vm is long life */
+#elif defined(MRB_HIGH_PROFILE)
+# ifndef MRB_METHOD_CACHE
+#  define MRB_METHOD_CACHE
+# endif
+
+# ifndef MRB_METHOD_CACHE_SIZE
+#  define MRB_METHOD_CACHE_SIZE (1<<12)
+# endif
+
+# ifndef MRB_IV_SEGMENT_SIZE
+#  define MRB_IV_SEGMENT_SIZE 64
+# endif
+
+# ifndef MRB_HEAP_PAGE_SIZE
+#  define MRB_HEAP_PAGE_SIZE 4096
+# endif
+#endif
+
 #endif  /* MRUBYCONF_H */
index 5b0d84c..5aba293 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ** mruby - An embeddable Ruby implementation
 **
-** Copyright (c) mruby developers 2010-2019
+** Copyright (c) mruby developers 2010-2020
 **
 ** Permission is hereby granted, free of charge, to any person obtaining
 ** a copy of this software and associated documentation files (the
 ** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
 */
 
+/**
+ * @file mruby.h
+ */
+
 #ifndef MRUBY_H
 #define MRUBY_H
 
 
 #include "mrbconf.h"
 
+#include <mruby/common.h>
+#include <mruby/value.h>
+#include <mruby/gc.h>
+#include <mruby/version.h>
+
 #ifndef MRB_WITHOUT_FLOAT
+#include <float.h>
 #ifndef FLT_EPSILON
 #define FLT_EPSILON (1.19209290e-07f)
 #endif
 #endif
 #endif
 
-#include "mruby/common.h"
-#include <mruby/value.h>
-#include <mruby/gc.h>
-#include <mruby/version.h>
-
 /**
  * MRuby C API entry point
  */
@@ -97,11 +102,14 @@ MRB_BEGIN_DECL
 typedef uint8_t mrb_code;
 
 /**
- * Required arguments signature type.
+ * \class mrb_aspec
+ *
+ * Specifies the number of arguments a function takes
+ *
+ * Example: `MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1)` for a method that expects 2..3 arguments
  */
 typedef uint32_t mrb_aspec;
 
-
 struct mrb_irep;
 struct mrb_state;
 
@@ -127,8 +135,8 @@ typedef struct {
   uint16_t ridx;
   uint16_t epos;
   struct REnv *env;
-  mrb_code *pc;                 /* return address */
-  mrb_code *err;                /* error position */
+  const mrb_code *pc;           /* return address */
+  const mrb_code *err;          /* error position */
   int argc;
   int acc;
   struct RClass *target_class;
@@ -157,8 +165,8 @@ struct mrb_context {
   struct RProc **ensure;                  /* ensure handler stack */
   uint16_t esize, eidx;
 
-  enum mrb_fiber_state status;
-  mrb_bool vmexec;
+  enum mrb_fiber_state status : 4;
+  mrb_bool vmexec : 1;
   struct RFiber *fib;
 };
 
@@ -170,13 +178,22 @@ struct mrb_context {
 # define MRB_METHOD_CACHE_SIZE (1<<7)
 #endif
 
-typedef mrb_value (*mrb_func_t)(struct mrb_state *mrb, mrb_value);
+/**
+ * Function pointer type for a function callable by mruby.
+ *
+ * The arguments to the function are stored on the mrb_state. To get them see mrb_get_args
+ *
+ * @param mrb The mruby state
+ * @param self The self object
+ * @return [mrb_value] The function's return value
+ */
+typedef mrb_value (*mrb_func_t)(struct mrb_state *mrb, mrb_value self);
 
-#ifdef MRB_METHOD_TABLE_INLINE
+#ifndef MRB_METHOD_T_STRUCT
 typedef uintptr_t mrb_method_t;
 #else
 typedef struct {
-  mrb_bool func_p;
+  uint8_t flags;
   union {
     struct RProc *proc;
     mrb_func_t func;
@@ -196,13 +213,9 @@ struct mrb_jmpbuf;
 
 typedef void (*mrb_atexit_func)(struct mrb_state*);
 
-#define MRB_STATE_NO_REGEXP 1
-#define MRB_STATE_REGEXP    2
-
 typedef struct mrb_state {
   struct mrb_jmpbuf *jmp;
 
-  uint32_t flags;
   mrb_allocf allocf;                      /* memory allocation function */
   void *allocf_ud;                        /* auxiliary data of allocf */
 
@@ -232,7 +245,6 @@ typedef struct mrb_state {
   struct RClass *symbol_class;
   struct RClass *kernel_module;
 
-  struct alloca_header *mems;
   mrb_gc gc;
 
 #ifdef MRB_METHOD_CACHE
@@ -248,8 +260,8 @@ typedef struct mrb_state {
 #endif
 
 #ifdef MRB_ENABLE_DEBUG_HOOK
-  void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs);
-  void (*debug_op_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs);
+  void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs);
+  void (*debug_op_hook)(struct mrb_state* mrb, struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs);
 #endif
 
 #ifdef MRB_BYTECODE_DECODE_OPTION
@@ -290,9 +302,9 @@ typedef struct mrb_state {
  *          //free(TheAnimals);
  *      }
  *
- * @param [mrb_state *] mrb The current mruby state.
- * @param [const char *] name The name of the defined class.
- * @param [struct RClass *] super The new class parent.
+ * @param mrb The current mruby state.
+ * @param name The name of the defined class.
+ * @param super The new class parent.
  * @return [struct RClass *] Reference to the newly defined class.
  * @see mrb_define_class_under
  */
@@ -301,12 +313,14 @@ MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct
 /**
  * Defines a new module.
  *
- * @param [mrb_state *] mrb_state* The current mruby state.
- * @param [const char *] char* The name of the module.
+ * @param mrb The current mruby state.
+ * @param name The name of the module.
  * @return [struct RClass *] Reference to the newly defined module.
  */
-MRB_API struct RClass *mrb_define_module(mrb_state *, const char*);
-MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value);
+MRB_API struct RClass *mrb_define_module(mrb_state *mrb, const char *name);
+
+MRB_API mrb_value mrb_singleton_class(mrb_state *mrb, mrb_value val);
+MRB_API struct RClass *mrb_singleton_class_ptr(mrb_state *mrb, mrb_value val);
 
 /**
  * Include a module in another class or module.
@@ -315,11 +329,11 @@ MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value);
  *   module B
  *     include A
  *   end
- * @param [mrb_state *] mrb_state* The current mruby state.
- * @param [struct RClass *] RClass* A reference to module or a class.
- * @param [struct RClass *] RClass* A reference to the module to be included.
+ * @param mrb The current mruby state.
+ * @param cla A reference to module or a class.
+ * @param included A reference to the module to be included.
  */
-MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*);
+MRB_API void mrb_include_module(mrb_state *mrb, struct RClass *cla, struct RClass *included);
 
 /**
  * Prepends a module in another class or module.
@@ -328,11 +342,11 @@ MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*);
  *  module B
  *    prepend A
  *  end
- * @param [mrb_state *] mrb_state* The current mruby state.
- * @param [struct RClass *] RClass* A reference to module or a class.
- * @param [struct RClass *] RClass* A reference to the module to be prepended.
+ * @param mrb The current mruby state.
+ * @param cla A reference to module or a class.
+ * @param prepended A reference to the module to be prepended.
  */
-MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*);
+MRB_API void mrb_prepend_module(mrb_state *mrb, struct RClass *cla, struct RClass *prepended);
 
 /**
  * Defines a global function in ruby.
@@ -341,7 +355,6 @@ MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*);
  *
  * Example:
  *
- *     !!!c
  *     mrb_value example_method(mrb_state* mrb, mrb_value self)
  *     {
  *          puts("Executing example command!");
@@ -353,11 +366,11 @@ MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*);
  *           mrb_define_method(mrb, mrb->kernel_module, "example_method", example_method, MRB_ARGS_NONE());
  *     }
  *
- * @param [mrb_state *] mrb The MRuby state reference.
- * @param [struct RClass *] cla The class pointer where the method will be defined.
- * @param [const char *] name The name of the method being defined.
- * @param [mrb_func_t] func The function pointer to the method definition.
- * @param [mrb_aspec] aspec The method parameters declaration.
+ * @param mrb The MRuby state reference.
+ * @param cla The class pointer where the method will be defined.
+ * @param name The name of the method being defined.
+ * @param func The function pointer to the method definition.
+ * @param aspec The method parameters declaration.
  */
 MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t func, mrb_aspec aspec);
 
@@ -380,14 +393,20 @@ MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *n
  *       foo = mrb_define_class(mrb, "Foo", mrb->object_class);
  *       mrb_define_class_method(mrb, foo, "bar", bar_method, MRB_ARGS_NONE());
  *     }
- * @param [mrb_state *] mrb_state* The MRuby state reference.
- * @param [struct RClass *] RClass* The class where the class method will be defined.
- * @param [const char *] char* The name of the class method being defined.
- * @param [mrb_func_t] mrb_func_t The function pointer to the class method definition.
- * @param [mrb_aspec] mrb_aspec The method parameters declaration.
+ * @param mrb The MRuby state reference.
+ * @param cla The class where the class method will be defined.
+ * @param name The name of the class method being defined.
+ * @param fun The function pointer to the class method definition.
+ * @param aspec The method parameters declaration.
+ */
+MRB_API void mrb_define_class_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t fun, mrb_aspec aspec);
+
+/**
+ * Defines a singleton method
+ *
+ * @see mrb_define_class_method
  */
-MRB_API void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, mrb_aspec);
-MRB_API void mrb_define_singleton_method(mrb_state*, struct RObject*, const char*, mrb_func_t, mrb_aspec);
+MRB_API void mrb_define_singleton_method(mrb_state *mrb, struct RObject *cla, const char *name, mrb_func_t fun, mrb_aspec aspec);
 
 /**
  *  Defines a module function.
@@ -408,13 +427,13 @@ MRB_API void mrb_define_singleton_method(mrb_state*, struct RObject*, const char
  *          foo = mrb_define_module(mrb, "Foo");
  *          mrb_define_module_function(mrb, foo, "bar", bar_method, MRB_ARGS_NONE());
  *        }
- *  @param [mrb_state *] mrb_state* The MRuby state reference.
- *  @param [struct RClass *] RClass* The module where the module function will be defined.
- *  @param [const char *] char* The name of the module function being defined.
- *  @param [mrb_func_t] mrb_func_t The function pointer to the module function definition.
- *  @param [mrb_aspec] mrb_aspec The method parameters declaration.
+ *  @param mrb The MRuby state reference.
+ *  @param cla The module where the module function will be defined.
+ *  @param name The name of the module function being defined.
+ *  @param fun The function pointer to the module function definition.
+ *  @param aspec The method parameters declaration.
  */
-MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec);
+MRB_API void mrb_define_module_function(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t fun, mrb_aspec aspec);
 
 /**
  *  Defines a constant.
@@ -437,12 +456,12 @@ MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*,
  *          mrb_value
  *          mrb_example_gem_final(mrb_state* mrb){
  *          }
- *  @param [mrb_state *] mrb_state* The MRuby state reference.
- *  @param [struct RClass *] RClass* A class or module the constant is defined in.
- *  @param [const char *] name The name of the constant being defined.
- *  @param [mrb_value] mrb_value The value for the constant.
+ *  @param mrb The MRuby state reference.
+ *  @param cla A class or module the constant is defined in.
+ *  @param name The name of the constant being defined.
+ *  @param val The value for the constant.
  */
-MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value);
+MRB_API void mrb_define_const(mrb_state* mrb, struct RClass* cla, const char *name, mrb_value val);
 
 /**
  * Undefines a method.
@@ -488,11 +507,11 @@ MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_
  *
  *     mrb_example_gem_final(mrb_state* mrb){
  *     }
- * @param [mrb_state*] mrb_state* The mruby state reference.
- * @param [struct RClass*] RClass* A class the method will be undefined from.
- * @param [const char*] const char* The name of the method to be undefined.
+ * @param mrb The mruby state reference.
+ * @param cla The class the method will be undefined from.
+ * @param name The name of the method to be undefined.
  */
-MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*);
+MRB_API void mrb_undef_method(mrb_state *mrb, struct RClass *cla, const char *name);
 MRB_API void mrb_undef_method_id(mrb_state*, struct RClass*, mrb_sym);
 
 /**
@@ -528,11 +547,11 @@ MRB_API void mrb_undef_method_id(mrb_state*, struct RClass*, mrb_sym);
  *      void
  *      mrb_example_gem_final(mrb_state* mrb){
  *      }
- * @param [mrb_state*] mrb_state* The mruby state reference.
- * @param [RClass*] RClass* A class the class method will be undefined from.
- * @param [const char*] const char* The name of the class method to be undefined.
+ * @param mrb The mruby state reference.
+ * @param cls A class the class method will be undefined from.
+ * @param name The name of the class method to be undefined.
  */
-MRB_API void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);
+MRB_API void mrb_undef_class_method(mrb_state *mrb, struct RClass *cls, const char *name);
 
 /**
  * Initialize a new object instance of c class.
@@ -556,10 +575,10 @@ MRB_API void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);
  *       obj = mrb_obj_new(mrb, example_class, 0, NULL); # => ExampleClass.new
  *       mrb_p(mrb, obj); // => Kernel#p
  *      }
- * @param [mrb_state*] mrb The current mruby state.
- * @param [RClass*] c Reference to the class of the new object.
- * @param [mrb_int] argc Number of arguments in argv
- * @param [const mrb_value *] argv Array of mrb_value to initialize the object
+ * @param mrb The current mruby state.
+ * @param c Reference to the class of the new object.
+ * @param argc Number of arguments in argv
+ * @param argv Array of mrb_value to initialize the object
  * @return [mrb_value] The newly initialized object
  */
 MRB_API mrb_value mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv);
@@ -570,8 +589,6 @@ MRB_INLINE mrb_value mrb_class_new_instance(mrb_state *mrb, mrb_int argc, const
   return mrb_obj_new(mrb,c,argc,argv);
 }
 
-MRB_API mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
-
 /**
  * Creates a new instance of Class, Class.
  *
@@ -587,8 +604,8 @@ MRB_API mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
  *        mrb_p(mrb, obj); // => Kernel#p
  *       }
  *
- * @param [mrb_state*] mrb The current mruby state.
- * @param [struct RClass *] super The super class or parent.
+ * @param mrb The current mruby state.
+ * @param super The super class or parent.
  * @return [struct RClass *] Reference to the new class.
  */
 MRB_API struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super);
@@ -604,7 +621,7 @@ MRB_API struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super);
  *        example_module = mrb_module_new(mrb);
  *      }
  *
- * @param [mrb_state*] mrb The current mruby state.
+ * @param mrb The current mruby state.
  * @return [struct RClass *] Reference to the new module.
  */
 MRB_API struct RClass * mrb_module_new(mrb_state *mrb);
@@ -631,24 +648,24 @@ MRB_API struct RClass * mrb_module_new(mrb_state *mrb);
  *       }
  *      }
  *
- * @param [mrb_state*] mrb The current mruby state.
- * @param [const char *] name A string representing the name of the class.
+ * @param mrb The current mruby state.
+ * @param name A string representing the name of the class.
  * @return [mrb_bool] A boolean value.
  */
 MRB_API mrb_bool mrb_class_defined(mrb_state *mrb, const char *name);
 
 /**
  * Gets a class.
- * @param [mrb_state*] mrb The current mruby state.
- * @param [const char *] name The name of the class.
+ * @param mrb The current mruby state.
+ * @param name The name of the class.
  * @return [struct RClass *] A reference to the class.
 */
 MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name);
 
 /**
  * Gets a exception class.
- * @param [mrb_state*] mrb The current mruby state.
- * @param [const char *] name The name of the class.
+ * @param mrb The current mruby state.
+ * @param name The name of the class.
  * @return [struct RClass *] A reference to the class.
 */
 MRB_API struct RClass * mrb_exc_get(mrb_state *mrb, const char *name);
@@ -677,35 +694,35 @@ MRB_API struct RClass * mrb_exc_get(mrb_state *mrb, const char *name);
  *       }
  *      }
  *
- * @param [mrb_state*] mrb The current mruby state.
- * @param [struct RClass *] outer The name of the outer class.
- * @param [const char *] name A string representing the name of the inner class.
+ * @param mrb The current mruby state.
+ * @param outer The name of the outer class.
+ * @param name A string representing the name of the inner class.
  * @return [mrb_bool] A boolean value.
  */
 MRB_API mrb_bool mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name);
 
 /**
  * Gets a child class.
- * @param [mrb_state*] mrb The current mruby state.
- * @param [struct RClass *] outer The name of the parent class.
- * @param [const char *] name The name of the class.
+ * @param mrb The current mruby state.
+ * @param outer The name of the parent class.
+ * @param name The name of the class.
  * @return [struct RClass *] A reference to the class.
 */
 MRB_API struct RClass * mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name);
 
 /**
  * Gets a module.
- * @param [mrb_state*] mrb The current mruby state.
- * @param [const char *] name The name of the module.
+ * @param mrb The current mruby state.
+ * @param name The name of the module.
  * @return [struct RClass *] A reference to the module.
 */
 MRB_API struct RClass * mrb_module_get(mrb_state *mrb, const char *name);
 
 /**
  * Gets a module defined under another module.
- * @param [mrb_state*] mrb The current mruby state.
- * @param [struct RClass *] outer The name of the outer module.
- * @param [const char *] name The name of the module.
+ * @param mrb The current mruby state.
+ * @param outer The name of the outer module.
+ * @param name The name of the module.
  * @return [struct RClass *] A reference to the module.
 */
 MRB_API struct RClass * mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name);
@@ -719,8 +736,8 @@ MRB_API mrb_value mrb_notimplement_m(mrb_state*, mrb_value);
  *
  * Equivalent to:
  *   Object#dup
- * @param [mrb_state*] mrb The current mruby state.
- * @param [mrb_value] obj Object to be duplicate.
+ * @param mrb The current mruby state.
+ * @param obj Object to be duplicate.
  * @return [mrb_value] The newly duplicated object.
  */
 MRB_API mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj);
@@ -760,9 +777,9 @@ MRB_API mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj);
  *        }
  *      }
  *
- * @param [mrb_state*] mrb The current mruby state.
- * @param [struct RClass *] c A reference to a class.
- * @param [mrb_sym] mid A symbol referencing a method id.
+ * @param mrb The current mruby state.
+ * @param c A reference to a class.
+ * @param mid A symbol referencing a method id.
  * @return [mrb_bool] A boolean value.
  */
 MRB_API mrb_bool mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid);
@@ -770,10 +787,10 @@ MRB_API mrb_bool mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mi
 /**
  * Defines a new class under a given module
  *
- * @param [mrb_state*] mrb The current mruby state.
- * @param [struct RClass *] outer Reference to the module under which the new class will be defined
- * @param [const char *] name The name of the defined class
- * @param [struct RClass *] super The new class parent
+ * @param mrb The current mruby state.
+ * @param outer Reference to the module under which the new class will be defined
+ * @param name The name of the defined class
+ * @param super The new class parent
  * @return [struct RClass *] Reference to the newly defined class
  * @see mrb_define_class
  */
@@ -843,34 +860,93 @@ MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *o
  * | `S`  | {String}       | {mrb_value}       | when `!` follows, the value may be `nil`           |
  * | `A`  | {Array}        | {mrb_value}       | when `!` follows, the value may be `nil`           |
  * | `H`  | {Hash}         | {mrb_value}       | when `!` follows, the value may be `nil`           |
- * | `s`  | {String}       | char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil`       |
+ * | `s`  | {String}       | char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil`        |
  * | `z`  | {String}       | char *            | `NULL` terminated string; `z!` gives `NULL` for `nil`           |
  * | `a`  | {Array}        | {mrb_value} *, {mrb_int} | Receive two arguments; `a!` gives (`NULL`,`0`) for `nil` |
- * | `f`  | {Float}        | {mrb_float}       |                                                    |
- * | `i`  | {Integer}      | {mrb_int}         |                                                    |
+ * | `f`  | {Fixnum}/{Float} | {mrb_float}       |                                                    |
+ * | `i`  | {Fixnum}/{Float} | {mrb_int}         |                                                    |
  * | `b`  | boolean        | {mrb_bool}        |                                                    |
- * | `n`  | {Symbol}       | {mrb_sym}         |                                                    |
+ * | `n`  | {String}/{Symbol} | {mrb_sym}         |                                                    |
+ * | `d`  | data           | void *, {mrb_data_type} const | 2nd argument will be used to check data type so it won't be modified; when `!` follows, the value may be `nil` |
+ * | `I`  | inline struct  | void *          |                                                    |
  * | `&`  | block          | {mrb_value}       | &! raises exception if no block given.             |
- * | `*`  | rest arguments | {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array; *! avoid copy of the stack.  |
- * | &vert; | optional     |                   | After this spec following specs would be optional. |
+ * | `*`  | rest arguments | {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array; `*!` avoid copy of the stack.  |
+ * | <code>\|</code> | optional     |                   | After this spec following specs would be optional. |
  * | `?`  | optional given | {mrb_bool}        | `TRUE` if preceding argument is given. Used to check optional argument is given. |
+ * | `:`  | keyword args   | {mrb_kwargs} const | Get keyword arguments. @see mrb_kwargs |
  *
  * @see mrb_get_args
  */
 typedef const char *mrb_args_format;
 
 /**
+ * Get keyword arguments by `mrb_get_args()` with `:` specifier.
+ *
+ * `mrb_kwargs::num` indicates that the number of keyword values.
+ *
+ * `mrb_kwargs::values` is an object array, and the keyword argument corresponding to the string array is assigned.
+ * Note that `undef` is assigned if there is no keyword argument corresponding to `mrb_kwargs::optional`.
+ *
+ * `mrb_kwargs::table` accepts a string array.
+ *
+ * `mrb_kwargs::required` indicates that the specified number of keywords starting from the beginning of the string array are required.
+ *
+ * `mrb_kwargs::rest` is the remaining keyword argument that can be accepted as `**rest` in Ruby.
+ * If `NULL` is specified, `ArgumentError` is raised when there is an undefined keyword.
+ *
+ * Examples:
+ *
+ *      // def method(a: 1, b: 2)
+ *
+ *      uint32_t kw_num = 2;
+ *      const char *kw_names[kw_num] = { "a", "b" };
+ *      uint32_t kw_required = 0;
+ *      mrb_value kw_values[kw_num];
+ *      const mrb_kwargs kwargs = { kw_num, kw_values, kw_names, kw_required, NULL };
+ *
+ *      mrb_get_args(mrb, ":", &kwargs);
+ *      if (mrb_undef_p(kw_values[0])) { kw_values[0] = mrb_fixnum_value(1); }
+ *      if (mrb_undef_p(kw_values[1])) { kw_values[1] = mrb_fixnum_value(2); }
+ *
+ *
+ *      // def method(str, x:, y: 2, z: "default string", **opts)
+ *
+ *      mrb_value str, kw_rest;
+ *      uint32_t kw_num = 3;
+ *      const char *kw_names[kw_num] = { "x", "y", "z" };
+ *      uint32_t kw_required = 1;
+ *      mrb_value kw_values[kw_num];
+ *      const mrb_kwargs kwargs = { kw_num, kw_values, kw_names, kw_required, &kw_rest };
+ *
+ *      mrb_get_args(mrb, "S:", &str, &kwargs);
+ *      // or: mrb_get_args(mrb, ":S", &kwargs, &str);
+ *      if (mrb_undef_p(kw_values[1])) { kw_values[1] = mrb_fixnum_value(2); }
+ *      if (mrb_undef_p(kw_values[2])) { kw_values[2] = mrb_str_new_cstr(mrb, "default string"); }
+ */
+typedef struct mrb_kwargs mrb_kwargs;
+
+struct mrb_kwargs
+{
+  uint32_t num;
+  mrb_value *values;
+  const char *const *table;
+  uint32_t required;
+  mrb_value *rest;
+};
+
+/**
  * Retrieve arguments from mrb_state.
  *
  * @param mrb The current MRuby state.
- * @param format [mrb_args_format] is a list of format specifiers
+ * @param format is a list of format specifiers
  * @param ... The passing variadic arguments must be a pointer of retrieving type.
  * @return the number of arguments retrieved.
  * @see mrb_args_format
+ * @see mrb_kwargs
  */
 MRB_API mrb_int mrb_get_args(mrb_state *mrb, mrb_args_format format, ...);
 
-static inline mrb_sym
+MRB_INLINE mrb_sym
 mrb_get_mid(mrb_state *mrb) /* get method symbol */
 {
   return mrb->c->ci->mid;
@@ -883,8 +959,21 @@ mrb_get_mid(mrb_state *mrb) /* get method symbol */
  */
 MRB_API mrb_int mrb_get_argc(mrb_state *mrb);
 
+/**
+ * Retrieve an array of arguments from mrb_state.
+ *
+ * Correctly handles *splat arguments.
+ */
 MRB_API mrb_value* mrb_get_argv(mrb_state *mrb);
 
+/**
+ * Retrieve the first and only argument from mrb_state.
+ * Raises ArgumentError unless the number of arguments is exactly one.
+ *
+ * Correctly handles *splat arguments.
+ */
+MRB_API mrb_value mrb_get_arg1(mrb_state *mrb);
+
 /* `strlen` for character string literals (use with caution or `strlen` instead)
     Adjacent string literals are concatenated in C/C++ in translation phase 6.
     If `lit` is not one, the compiler will report a syntax error:
@@ -896,6 +985,8 @@ MRB_API mrb_value* mrb_get_argv(mrb_state *mrb);
 /**
  * Call existing ruby functions.
  *
+ * Example:
+ *
  *      #include <stdio.h>
  *      #include <mruby.h>
  *      #include "mruby/compile.h"
@@ -912,15 +1003,16 @@ MRB_API mrb_value* mrb_get_argv(mrb_state *mrb);
  *        mrb_funcall(mrb, obj, "method_name", 1, mrb_fixnum_value(i));
  *        fclose(fp);
  *        mrb_close(mrb);
- *       }
- * @param [mrb_state*] mrb_state* The current mruby state.
- * @param [mrb_value] mrb_value A reference to an mruby value.
- * @param [const char*] const char* The name of the method.
- * @param [mrb_int] mrb_int The number of arguments the method has.
- * @param [...] ... Variadic values(not type safe!).
- * @return [mrb_value] mrb_value mruby function value.
+ *      }
+ *
+ * @param mrb The current mruby state.
+ * @param val A reference to an mruby value.
+ * @param name The name of the method.
+ * @param argc The number of arguments the method has.
+ * @param ... Variadic values(not type safe!).
+ * @return [mrb_value] mruby function value.
  */
-MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...);
+MRB_API mrb_value mrb_funcall(mrb_state *mrb, mrb_value val, const char *name, mrb_int argc, ...);
 /**
  * Call existing ruby functions. This is basically the type safe version of mrb_funcall.
  *
@@ -942,32 +1034,35 @@ MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...);
  *        fclose(fp);
  *        mrb_close(mrb);
  *       }
- * @param [mrb_state*] mrb_state* The current mruby state.
- * @param [mrb_value] mrb_value A reference to an mruby value.
- * @param [mrb_sym] mrb_sym The symbol representing the method.
- * @param [mrb_int] mrb_int The number of arguments the method has.
- * @param [const mrb_value*] mrb_value* Pointer to the object.
+ * @param mrb The current mruby state.
+ * @param val A reference to an mruby value.
+ * @param name_sym The symbol representing the method.
+ * @param argc The number of arguments the method has.
+ * @param obj Pointer to the object.
  * @return [mrb_value] mrb_value mruby function value.
  * @see mrb_funcall
  */
-MRB_API mrb_value mrb_funcall_argv(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*);
+MRB_API mrb_value mrb_funcall_argv(mrb_state *mrb, mrb_value val, mrb_sym name, mrb_int argc, const mrb_value *argv);
 /**
  * Call existing ruby functions with a block.
  */
-MRB_API mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*, mrb_value);
+MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value val, mrb_sym name, mrb_int argc, const mrb_value *argv, mrb_value block);
 /**
  * Create a symbol
  *
+ * Example:
+ *
  *     # Ruby style:
  *     :pizza # => :pizza
  *
  *     // C style:
  *     mrb_sym m_sym = mrb_intern_lit(mrb, "pizza"); //  => :pizza
- * @param [mrb_state*] mrb_state* The current mruby state.
- * @param [const char*] const char* The name of the method.
+ *
+ * @param mrb The current mruby state.
+ * @param str The string to be symbolized
  * @return [mrb_sym] mrb_sym A symbol.
  */
-MRB_API mrb_sym mrb_intern_cstr(mrb_state*,const char*);
+MRB_API mrb_sym mrb_intern_cstr(mrb_state *mrb, const char* str);
 MRB_API mrb_sym mrb_intern(mrb_state*,const char*,size_t);
 MRB_API mrb_sym mrb_intern_static(mrb_state*,const char*,size_t);
 #define mrb_intern_lit(mrb, lit) mrb_intern_static(mrb, lit, mrb_strlen_lit(lit))
@@ -975,9 +1070,13 @@ MRB_API mrb_sym mrb_intern_str(mrb_state*,mrb_value);
 MRB_API mrb_value mrb_check_intern_cstr(mrb_state*,const char*);
 MRB_API mrb_value mrb_check_intern(mrb_state*,const char*,size_t);
 MRB_API mrb_value mrb_check_intern_str(mrb_state*,mrb_value);
-MRB_API const char *mrb_sym2name(mrb_state*,mrb_sym);
-MRB_API const char *mrb_sym2name_len(mrb_state*,mrb_sym,mrb_int*);
-MRB_API mrb_value mrb_sym2str(mrb_state*,mrb_sym);
+MRB_API const char *mrb_sym_name(mrb_state*,mrb_sym);
+MRB_API const char *mrb_sym_name_len(mrb_state*,mrb_sym,mrb_int*);
+MRB_API const char *mrb_sym_dump(mrb_state*,mrb_sym);
+MRB_API mrb_value mrb_sym_str(mrb_state*,mrb_sym);
+#define mrb_sym2name(mrb,sym) mrb_sym_name(mrb,sym)
+#define mrb_sym2name_len(mrb,sym,len) mrb_sym_name_len(mrb,sym,len)
+#define mrb_sym2str(mrb,sym) mrb_sym_str(mrb,sym)
 
 MRB_API void *mrb_malloc(mrb_state*, size_t);         /* raise RuntimeError if no mem */
 MRB_API void *mrb_calloc(mrb_state*, size_t, size_t); /* ditto */
@@ -996,6 +1095,12 @@ MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*);
 MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len);
 #define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit))
 
+MRB_API mrb_value mrb_obj_freeze(mrb_state*, mrb_value);
+#define mrb_str_new_frozen(mrb,p,len) mrb_obj_freeze(mrb,mrb_str_new(mrb,p,len))
+#define mrb_str_new_cstr_frozen(mrb,p) mrb_obj_freeze(mrb,mrb_str_new_cstr(mrb,p))
+#define mrb_str_new_static_frozen(mrb,p,len) mrb_obj_freeze(mrb,mrb_str_new_static(mrb,p,len))
+#define mrb_str_new_lit_frozen(mrb,lit) mrb_obj_freeze(mrb,mrb_str_new_lit(mrb,lit))
+
 #ifdef _WIN32
 MRB_API char* mrb_utf8_from_locale(const char *p, int len);
 MRB_API char* mrb_locale_from_utf8(const char *p, int len);
@@ -1058,11 +1163,10 @@ MRB_API void mrb_close(mrb_state *mrb);
  */
 MRB_API void* mrb_default_allocf(mrb_state*, void*, size_t, void*);
 
-MRB_API mrb_value mrb_top_self(mrb_state *);
-MRB_API mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value);
-MRB_API mrb_value mrb_top_run(mrb_state*, struct RProc*, mrb_value, unsigned int);
-MRB_API mrb_value mrb_vm_run(mrb_state*, struct RProc*, mrb_value, unsigned int);
-MRB_API mrb_value mrb_vm_exec(mrb_state*, struct RProc*, mrb_code*);
+MRB_API mrb_value mrb_top_self(mrb_state *mrb);
+MRB_API mrb_value mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep);
+MRB_API mrb_value mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep);
+MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *iseq);
 /* compatibility macros */
 #define mrb_toplevel_run_keep(m,p,k) mrb_top_run((m),(p),mrb_top_self(m),(k))
 #define mrb_toplevel_run(m,p) mrb_toplevel_run_keep((m),(p),0)
@@ -1072,8 +1176,8 @@ MRB_API void mrb_p(mrb_state*, mrb_value);
 MRB_API mrb_int mrb_obj_id(mrb_value obj);
 MRB_API mrb_sym mrb_obj_to_sym(mrb_state *mrb, mrb_value name);
 
-MRB_API mrb_bool mrb_obj_eq(mrb_state*, mrb_value, mrb_value);
-MRB_API mrb_bool mrb_obj_equal(mrb_state*, mrb_value, mrb_value);
+MRB_API mrb_bool mrb_obj_eq(mrb_state *mrb, mrb_value a, mrb_value b);
+MRB_API mrb_bool mrb_obj_equal(mrb_state *mrb, mrb_value a, mrb_value b);
 MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
 MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base);
 MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val);
@@ -1082,17 +1186,16 @@ MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val);
 #endif
 MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj);
 MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
+/* mrb_cmp(mrb, obj1, obj2): 1:0:-1; -2 for error */
+MRB_API mrb_int mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
 
-static inline int mrb_gc_arena_save(mrb_state*);
-static inline void mrb_gc_arena_restore(mrb_state*,int);
-
-static inline int
+MRB_INLINE int
 mrb_gc_arena_save(mrb_state *mrb)
 {
   return mrb->gc.arena_idx;
 }
 
-static inline void
+MRB_INLINE void
 mrb_gc_arena_restore(mrb_state *mrb, int idx)
 {
   mrb->gc.arena_idx = idx;
@@ -1143,6 +1246,8 @@ MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc);
 MRB_API mrb_noreturn void mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg);
 MRB_API mrb_noreturn void mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...);
 MRB_API mrb_noreturn void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...);
+MRB_API mrb_noreturn void mrb_frozen_error(mrb_state *mrb, void *frozen_obj);
+MRB_API mrb_noreturn void mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max);
 MRB_API void mrb_warn(mrb_state *mrb, const char *fmt, ...);
 MRB_API mrb_noreturn void mrb_bug(mrb_state *mrb, const char *fmt, ...);
 MRB_API void mrb_print_backtrace(mrb_state *mrb);
@@ -1193,9 +1298,15 @@ MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj);
 
 MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val);
 #define mrb_int(mrb, val) mrb_fixnum(mrb_to_int(mrb, val))
+/* string type checking (contrary to the name, it doesn't convert) */
 MRB_API mrb_value mrb_to_str(mrb_state *mrb, mrb_value val);
 MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t);
 
+MRB_INLINE void mrb_check_frozen(mrb_state *mrb, void *o)
+{
+  if (mrb_frozen_p((struct RBasic*)o)) mrb_frozen_error(mrb, o);
+}
+
 typedef enum call_type {
   CALL_PUBLIC,
   CALL_FCALL,
@@ -1214,31 +1325,31 @@ MRB_API mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RC
 MRB_API mrb_bool mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func);
 
 
-/*
+/**
  * Resume a Fiber
  *
- * @mrbgem mruby-fiber
+ * Implemented in mruby-fiber
  */
 MRB_API mrb_value mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int argc, const mrb_value *argv);
 
-/*
+/**
  * Yield a Fiber
  *
- * @mrbgem mruby-fiber
+ * Implemented in mruby-fiber
  */
 MRB_API mrb_value mrb_fiber_yield(mrb_state *mrb, mrb_int argc, const mrb_value *argv);
 
-/*
+/**
  * Check if a Fiber is alive
  *
- * @mrbgem mruby-fiber
+ * Implemented in mruby-fiber
  */
 MRB_API mrb_value mrb_fiber_alive_p(mrb_state *mrb, mrb_value fib);
 
-/*
+/**
  * FiberError reference
  *
- * @mrbgem mruby-fiber
+ * Implemented in mruby-fiber
  */
 #define E_FIBER_ERROR (mrb_exc_get(mrb, "FiberError"))
 MRB_API void mrb_stack_extend(mrb_state*, mrb_int);
@@ -1250,6 +1361,7 @@ MRB_API void mrb_pool_close(struct mrb_pool*);
 MRB_API void* mrb_pool_alloc(struct mrb_pool*, size_t);
 MRB_API void* mrb_pool_realloc(struct mrb_pool*, void*, size_t oldlen, size_t newlen);
 MRB_API mrb_bool mrb_pool_can_realloc(struct mrb_pool*, void*, size_t);
+/* temporary memory allocation, only effective while GC arena is kept */
 MRB_API void* mrb_alloca(mrb_state *mrb, size_t);
 
 MRB_API void mrb_state_atexit(mrb_state *mrb, mrb_atexit_func func);
index 2e6951c..92c86a8 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/array.h - Array class
+/**
+** @file mruby/array.h - Array class
 **
 ** See Copyright Notice in mruby.h
 */
@@ -17,7 +17,7 @@ MRB_BEGIN_DECL
 
 typedef struct mrb_shared_array {
   int refcnt;
-  mrb_int len;
+  mrb_ssize len;
   mrb_value *ptr;
 } mrb_shared_array;
 
@@ -26,14 +26,14 @@ struct RArray {
   MRB_OBJECT_HEADER;
   union {
     struct {
-      mrb_int len;
+      mrb_ssize len;
       union {
-        mrb_int capa;
+        mrb_ssize capa;
         mrb_shared_array *shared;
       } aux;
       mrb_value *ptr;
     } heap;
-    mrb_value embed[MRB_ARY_EMBED_LEN_MAX];
+    void *ary[3];
   } as;
 };
 
@@ -46,7 +46,7 @@ struct RArray {
 #define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK))
 #define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1))
 #define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((uint32_t)(len) + 1))
-#define ARY_EMBED_PTR(a) (&((a)->as.embed[0]))
+#define ARY_EMBED_PTR(a) ((mrb_value*)(&(a)->as.ary))
 
 #define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len)
 #define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr)
@@ -239,6 +239,7 @@ MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset);
  * @param head Beginning position of a replacement subsequence.
  * @param len Length of a replacement subsequence.
  * @param rpl The array of replacement elements.
+ *            It is possible to pass `mrb_undef_value()` instead of an empty array.
  * @return The receiver array.
  */
 MRB_API mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value self, mrb_int head, mrb_int len, mrb_value rpl);
@@ -291,6 +292,9 @@ MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep);
  */
 MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len);
 
+/* helper functions */
+mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len);
+
 MRB_END_DECL
 
 #endif  /* MRUBY_ARRAY_H */
index ff6f608..fae3b76 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/boxing_nan.h - nan boxing mrb_value definition
+/**
+** @file mruby/boxing_nan.h - nan boxing mrb_value definition
 **
 ** See Copyright Notice in mruby.h
 */
 #endif
 
 #define MRB_FIXNUM_SHIFT 0
-#define MRB_TT_HAS_BASIC MRB_TT_OBJECT
-
-#ifdef MRB_ENDIAN_BIG
-#define MRB_ENDIAN_LOHI(a,b) a b
-#else
-#define MRB_ENDIAN_LOHI(a,b) b a
-#endif
+#define MRB_SYMBOL_SHIFT 0
 
 /* value representation by nan-boxing:
  *   float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
@@ -50,6 +44,9 @@ typedef struct mrb_value {
           };
         )
       };
+#ifdef MRB_64BIT
+      struct RCptr *vp;
+#endif
     } value;
   };
 } mrb_value;
@@ -60,13 +57,15 @@ typedef struct mrb_value {
 #define mrb_type(o)     (enum mrb_vtype)((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT)
 #define mrb_ptr(o)      ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)((o).value.p)))<<2))
 #define mrb_float(o)    (o).f
-#define mrb_cptr(o)     mrb_ptr(o)
 #define mrb_fixnum(o)   (o).value.i
 #define mrb_symbol(o)   (o).value.sym
 
 #ifdef MRB_64BIT
+MRB_API mrb_value mrb_nan_boxing_cptr_value(struct mrb_state*, void*);
+#define mrb_cptr(o)     (((struct RCptr*)mrb_ptr(o))->p)
 #define BOXNAN_SHIFT_LONG_POINTER(v) (((uintptr_t)(v)>>34)&0x3fff)
 #else
+#define mrb_cptr(o)     ((o).value.p)
 #define BOXNAN_SHIFT_LONG_POINTER(v) 0
 #endif
 
@@ -96,7 +95,11 @@ typedef struct mrb_value {
 #define SET_INT_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
 #define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
 #define SET_OBJ_VALUE(r,v) BOXNAN_SET_OBJ_VALUE(r, (((struct RObject*)(v))->tt), (v))
-#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_OBJ_VALUE(r, MRB_TT_CPTR, v)
+#ifdef MRB_64BIT
+#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_nan_boxing_cptr_value(mrb, v))
+#else
+#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
+#endif
 #define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
 
 #endif  /* MRUBY_BOXING_NAN_H */
index 86ce645..7573428 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/boxing_no.h - unboxed mrb_value definition
+/**
+** @file mruby/boxing_no.h - unboxed mrb_value definition
 **
 ** See Copyright Notice in mruby.h
 */
@@ -8,17 +8,19 @@
 #define MRUBY_BOXING_NO_H
 
 #define MRB_FIXNUM_SHIFT 0
-#define MRB_TT_HAS_BASIC MRB_TT_OBJECT
+#define MRB_SYMBOL_SHIFT 0
 
-typedef struct mrb_value {
-  union {
+union mrb_value_union {
 #ifndef MRB_WITHOUT_FLOAT
-    mrb_float f;
+  mrb_float f;
 #endif
-    void *p;
-    mrb_int i;
-    mrb_sym sym;
-  } value;
+  void *p;
+  mrb_int i;
+  mrb_sym sym;
+};
+
+typedef struct mrb_value {
+  union mrb_value_union value;
   enum mrb_vtype tt;
 } mrb_value;
 
index 3b7167b..1b7815b 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/boxing_word.h - word boxing mrb_value definition
+/**
+** @file mruby/boxing_word.h - word boxing mrb_value definition
 **
 ** See Copyright Notice in mruby.h
 */
@@ -7,10 +7,6 @@
 #ifndef MRUBY_BOXING_WORD_H
 #define MRUBY_BOXING_WORD_H
 
-#if defined(MRB_INT16)
-# error MRB_INT16 is too small for MRB_WORD_BOXING.
-#endif
-
 #if defined(MRB_INT64) && !defined(MRB_64BIT)
 #error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode.
 #endif
@@ -22,48 +18,66 @@ struct RFloat {
 };
 #endif
 
-struct RCptr {
-  MRB_OBJECT_HEADER;
-  void *p;
+enum mrb_special_consts {
+  MRB_Qnil    =  0,
+  MRB_Qfalse  =  4,
+  MRB_Qtrue   = 12,
+  MRB_Qundef  = 20,
 };
 
-#define MRB_FIXNUM_SHIFT 1
-#ifdef MRB_WITHOUT_FLOAT
-#define MRB_TT_HAS_BASIC MRB_TT_CPTR
+#if defined(MRB_64BIT) && defined(MRB_INT32)
+#define MRB_FIXNUM_SHIFT        0
 #else
-#define MRB_TT_HAS_BASIC MRB_TT_FLOAT
+#define MRB_FIXNUM_SHIFT        BOXWORD_FIXNUM_SHIFT
 #endif
+#define MRB_SYMBOL_SHIFT        BOXWORD_SYMBOL_SHIFT
 
-enum mrb_special_consts {
-  MRB_Qnil    = 0,
-  MRB_Qfalse  = 2,
-  MRB_Qtrue   = 4,
-  MRB_Qundef  = 6,
-};
-
-#define MRB_FIXNUM_FLAG   0x01
-#define MRB_SYMBOL_FLAG   0x0e
-#define MRB_SPECIAL_SHIFT 8
-
-#if defined(MRB_64BIT)
-#define MRB_SYMBOL_BITSIZE  (sizeof(mrb_sym) * CHAR_BIT)
-#define MRB_SYMBOL_MAX      UINT32_MAX
+#define BOXWORD_FIXNUM_BIT_POS  1
+#define BOXWORD_SYMBOL_BIT_POS  2
+#define BOXWORD_FIXNUM_SHIFT    BOXWORD_FIXNUM_BIT_POS
+#ifdef MRB_64BIT
+#define BOXWORD_SYMBOL_SHIFT    0
 #else
-#define MRB_SYMBOL_BITSIZE  (sizeof(mrb_sym) * CHAR_BIT - MRB_SPECIAL_SHIFT)
-#define MRB_SYMBOL_MAX      (UINT32_MAX >> MRB_SPECIAL_SHIFT)
+#define BOXWORD_SYMBOL_SHIFT    BOXWORD_SYMBOL_BIT_POS
 #endif
+#define BOXWORD_FIXNUM_FLAG     (1 << (BOXWORD_FIXNUM_BIT_POS - 1))
+#define BOXWORD_SYMBOL_FLAG     (1 << (BOXWORD_SYMBOL_BIT_POS - 1))
+#define BOXWORD_FIXNUM_MASK     ((1 << BOXWORD_FIXNUM_BIT_POS) - 1)
+#define BOXWORD_SYMBOL_MASK     ((1 << BOXWORD_SYMBOL_BIT_POS) - 1)
+#define BOXWORD_IMMEDIATE_MASK  0x07
+
+#define BOXWORD_SHIFT_VALUE(o,n,t) \
+  (t)(((long)(o).w) >> BOXWORD_##n##_SHIFT)
+#define BOXWORD_SET_SHIFT_VALUE(o,n,v) \
+  ((o).w = (((unsigned long)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG)
+#define BOXWORD_SHIFT_VALUE_P(o,n) \
+  (((o).w & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG)
+#define BOXWORD_OBJ_TYPE_P(o,n) \
+  (!mrb_immediate_p(o) && (o).value.bp->tt == MRB_TT_##n)
 
+/*
+ * mrb_value representation:
+ *
+ *   nil   : ...0000 0000 (all bits are 0)
+ *   false : ...0000 0100 (mrb_fixnum(v) != 0)
+ *   true  : ...0000 1100
+ *   undef : ...0001 0100
+ *   fixnum: ...IIII III1
+ *   symbol: ...SSSS SS10 (use only upper 32-bit as symbol value on 64-bit CPU)
+ *   object: ...PPPP P000 (any bits are 1)
+ */
 typedef union mrb_value {
   union {
     void *p;
+#ifdef MRB_64BIT
+    /* use struct to avoid bit shift. */
     struct {
-      unsigned int i_flag : MRB_FIXNUM_SHIFT;
-      mrb_int i : (MRB_INT_BIT - MRB_FIXNUM_SHIFT);
-    };
-    struct {
-      unsigned int sym_flag : MRB_SPECIAL_SHIFT;
-      mrb_sym sym : MRB_SYMBOL_BITSIZE;
+      MRB_ENDIAN_LOHI(
+        mrb_sym sym;
+        ,uint32_t sym_flag;
+      )
     };
+#endif
     struct RBasic *bp;
 #ifndef MRB_WITHOUT_FLOAT
     struct RFloat *fp;
@@ -88,57 +102,73 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
 #ifndef MRB_WITHOUT_FLOAT
 #define mrb_float(o)   (o).value.fp->f
 #endif
-#define mrb_fixnum(o)  ((mrb_int)(o).value.i)
+#define mrb_fixnum(o)  BOXWORD_SHIFT_VALUE(o, FIXNUM, mrb_int)
+#ifdef MRB_64BIT
 #define mrb_symbol(o)  (o).value.sym
+#else
+#define mrb_symbol(o)  BOXWORD_SHIFT_VALUE(o, SYMBOL, mrb_sym)
+#endif
+#define mrb_bool(o)    (((o).w & ~(unsigned long)MRB_Qfalse) != 0)
 
-static inline enum mrb_vtype
-mrb_type(mrb_value o)
-{
-  switch (o.w) {
-  case MRB_Qfalse:
-  case MRB_Qnil:
-    return MRB_TT_FALSE;
-  case MRB_Qtrue:
-    return MRB_TT_TRUE;
-  case MRB_Qundef:
-    return MRB_TT_UNDEF;
-  }
-  if (o.value.i_flag == MRB_FIXNUM_FLAG) {
-    return MRB_TT_FIXNUM;
-  }
-  if (o.value.sym_flag == MRB_SYMBOL_FLAG) {
-    return MRB_TT_SYMBOL;
-  }
-  return o.value.bp->tt;
-}
-
-#define mrb_bool(o)    ((o).w != MRB_Qnil && (o).w != MRB_Qfalse)
-#define mrb_fixnum_p(o) ((o).value.i_flag == MRB_FIXNUM_FLAG)
+#define mrb_immediate_p(o) ((o).w & BOXWORD_IMMEDIATE_MASK || (o).w == MRB_Qnil)
+#define mrb_fixnum_p(o) BOXWORD_SHIFT_VALUE_P(o, FIXNUM)
+#ifdef MRB_64BIT
+#define mrb_symbol_p(o) ((o).value.sym_flag == BOXWORD_SYMBOL_FLAG)
+#else
+#define mrb_symbol_p(o) BOXWORD_SHIFT_VALUE_P(o, SYMBOL)
+#endif
 #define mrb_undef_p(o) ((o).w == MRB_Qundef)
 #define mrb_nil_p(o)  ((o).w == MRB_Qnil)
-
-#define BOXWORD_SET_VALUE(o, ttt, attr, v) do { \
-  switch (ttt) {\
-  case MRB_TT_FALSE:  (o).w = (v) ? MRB_Qfalse : MRB_Qnil; break;\
-  case MRB_TT_TRUE:   (o).w = MRB_Qtrue; break;\
-  case MRB_TT_UNDEF:  (o).w = MRB_Qundef; break;\
-  case MRB_TT_FIXNUM: (o).w = 0;(o).value.i_flag = MRB_FIXNUM_FLAG; (o).attr = (v); break;\
-  case MRB_TT_SYMBOL: (o).w = 0;(o).value.sym_flag = MRB_SYMBOL_FLAG; (o).attr = (v); break;\
-  default:            (o).w = 0; (o).attr = (v); if ((o).value.bp) (o).value.bp->tt = ttt; break;\
-  }\
-} while (0)
+#define mrb_false_p(o) ((o).w == MRB_Qfalse)
+#define mrb_true_p(o)  ((o).w == MRB_Qtrue)
+#ifndef MRB_WITHOUT_FLOAT
+#define mrb_float_p(o) BOXWORD_OBJ_TYPE_P(o, FLOAT)
+#endif
+#define mrb_array_p(o) BOXWORD_OBJ_TYPE_P(o, ARRAY)
+#define mrb_string_p(o) BOXWORD_OBJ_TYPE_P(o, STRING)
+#define mrb_hash_p(o) BOXWORD_OBJ_TYPE_P(o, HASH)
+#define mrb_cptr_p(o) BOXWORD_OBJ_TYPE_P(o, CPTR)
+#define mrb_exception_p(o) BOXWORD_OBJ_TYPE_P(o, EXCEPTION)
+#define mrb_free_p(o) BOXWORD_OBJ_TYPE_P(o, FREE)
+#define mrb_object_p(o) BOXWORD_OBJ_TYPE_P(o, OBJECT)
+#define mrb_class_p(o) BOXWORD_OBJ_TYPE_P(o, CLASS)
+#define mrb_module_p(o) BOXWORD_OBJ_TYPE_P(o, MODULE)
+#define mrb_iclass_p(o) BOXWORD_OBJ_TYPE_P(o, ICLASS)
+#define mrb_sclass_p(o) BOXWORD_OBJ_TYPE_P(o, SCLASS)
+#define mrb_proc_p(o) BOXWORD_OBJ_TYPE_P(o, PROC)
+#define mrb_range_p(o) BOXWORD_OBJ_TYPE_P(o, RANGE)
+#define mrb_env_p(o) BOXWORD_OBJ_TYPE_P(o, ENV)
+#define mrb_data_p(o) BOXWORD_OBJ_TYPE_P(o, DATA)
+#define mrb_fiber_p(o) BOXWORD_OBJ_TYPE_P(o, FIBER)
+#define mrb_istruct_p(o) BOXWORD_OBJ_TYPE_P(o, ISTRUCT)
+#define mrb_break_p(o) BOXWORD_OBJ_TYPE_P(o, BREAK)
 
 #ifndef MRB_WITHOUT_FLOAT
 #define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v))
 #endif
 #define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_word_boxing_cptr_value(mrb, v))
-#define SET_NIL_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
-#define SET_FALSE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
-#define SET_TRUE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
-#define SET_BOOL_VALUE(r,b) BOXWORD_SET_VALUE(r, (b) ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
-#define SET_INT_VALUE(r,n) BOXWORD_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
-#define SET_SYM_VALUE(r,v) BOXWORD_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
-#define SET_OBJ_VALUE(r,v) BOXWORD_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
-#define SET_UNDEF_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
+#define SET_UNDEF_VALUE(r) ((r).w = MRB_Qundef)
+#define SET_NIL_VALUE(r) ((r).w = MRB_Qnil)
+#define SET_FALSE_VALUE(r) ((r).w = MRB_Qfalse)
+#define SET_TRUE_VALUE(r) ((r).w = MRB_Qtrue)
+#define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r))
+#define SET_INT_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n)
+#ifdef MRB_64BIT
+#define SET_SYM_VALUE(r,v) ((r).value.sym = v, (r).value.sym_flag = BOXWORD_SYMBOL_FLAG)
+#else
+#define SET_SYM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, SYMBOL, n)
+#endif
+#define SET_OBJ_VALUE(r,v) ((r).value.p = v)
+
+MRB_INLINE enum mrb_vtype
+mrb_type(mrb_value o)
+{
+  return !mrb_bool(o)    ? MRB_TT_FALSE :
+         mrb_true_p(o)   ? MRB_TT_TRUE :
+         mrb_fixnum_p(o) ? MRB_TT_FIXNUM :
+         mrb_symbol_p(o) ? MRB_TT_SYMBOL :
+         mrb_undef_p(o)  ? MRB_TT_UNDEF :
+         o.value.bp->tt;
+}
 
 #endif  /* MRUBY_BOXING_WORD_H */
index b667e20..cbf96fe 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/class.h - Class class
+/**
+** @file mruby/class.h - Class class
 **
 ** See Copyright Notice in mruby.h
 */
@@ -23,7 +23,7 @@ struct RClass {
 
 #define mrb_class_ptr(v)    ((struct RClass*)(mrb_ptr(v)))
 
-static inline struct RClass*
+MRB_INLINE struct RClass*
 mrb_class(mrb_state *mrb, mrb_value v)
 {
   switch (mrb_type(v)) {
@@ -75,8 +75,8 @@ mrb_class(mrb_state *mrb, mrb_value v)
 
 MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*);
 MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym);
-MRB_API struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
-MRB_API struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
+struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
+struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
 MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t);
 MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec);
 MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b);
@@ -85,13 +85,22 @@ MRB_API mrb_method_t mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym);
 MRB_API mrb_method_t mrb_method_search(mrb_state*, struct RClass*, mrb_sym);
 
 MRB_API struct RClass* mrb_class_real(struct RClass* cl);
+mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
 
 void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym);
+mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int);
 mrb_value mrb_class_find_path(mrb_state*, struct RClass*);
+mrb_value mrb_mod_to_s(mrb_state*, mrb_value);
 void mrb_gc_mark_mt(mrb_state*, struct RClass*);
 size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
 void mrb_gc_free_mt(mrb_state*, struct RClass*);
 
+#ifdef MRB_METHOD_CACHE
+void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c);
+#else
+#define mrb_mc_clear_by_class(mrb,c)
+#endif
+
 MRB_END_DECL
 
 #endif  /* MRUBY_CLASS_H */
index 4eaac9a..f704ef8 100644 (file)
@@ -1,5 +1,5 @@
-/*
-**"common.h - mruby common platform definition"
+/**
+** @file common.h - mruby common platform definition"
 **
 ** See Copyright Notice in mruby.h
 */
@@ -54,14 +54,15 @@ MRB_BEGIN_DECL
 #endif
 
 /** Declare a function as always inlined. */
-#if defined(_MSC_VER)
-# define MRB_INLINE static __inline
-#else
-# define MRB_INLINE static inline
+#if defined _MSC_VER && _MSC_VER < 1900
+# ifndef __cplusplus
+#  define inline __inline
+# endif
 #endif
-
+#define MRB_INLINE static inline
 
 /** Declare a public MRuby API function. */
+#ifndef MRB_API
 #if defined(MRB_BUILD_AS_DLL)
 #if defined(MRB_CORE) || defined(MRB_LIB)
 # define MRB_API __declspec(dllexport)
@@ -71,6 +72,17 @@ MRB_BEGIN_DECL
 #else
 # define MRB_API extern
 #endif
+#endif
+
+/** Declare mingw versions */
+#if defined(__MINGW32__) || defined(__MINGW64__)
+# include <_mingw.h>
+# if defined(__MINGW64_VERSION_MAJOR)
+#  define MRB_MINGW64_VERSION  (__MINGW64_VERSION_MAJOR * 1000 + __MINGW64_VERSION_MINOR)
+# elif defined(__MINGW32_MAJOR_VERSION)
+#  define MRB_MINGW32_VERSION  (__MINGW32_MAJOR_VERSION * 1000 + __MINGW32_MINOR_VERSION)
+# endif
+#endif
 
 MRB_END_DECL
 
index f19d9b0..7b878d4 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/compile.h - mruby parser
+/**
+** @file mruby/compile.h - mruby parser
 **
 ** See Copyright Notice in mruby.h
 */
@@ -24,7 +24,7 @@ typedef struct mrbc_context {
   mrb_sym *syms;
   int slen;
   char *filename;
-  short lineno;
+  uint16_t lineno;
   int (*partial_hook)(struct mrb_parser_state*);
   void *partial_data;
   struct RClass *target_class;
@@ -33,7 +33,7 @@ typedef struct mrbc_context {
   mrb_bool no_exec:1;
   mrb_bool keep_lv:1;
   mrb_bool no_optimize:1;
-  mrb_bool on_eval:1;
+  struct RProc *upper;
 
   size_t parser_nerr;
 } mrbc_context;
@@ -67,7 +67,7 @@ enum mrb_lex_state_enum {
 
 /* saved error message */
 struct mrb_parser_message {
-  int lineno;
+  uint16_t lineno;
   int column;
   char* message;
 };
@@ -105,7 +105,7 @@ struct mrb_parser_heredoc_info {
   mrb_ast_node *doc;
 };
 
-#define MRB_PARSER_TOKBUF_MAX 65536
+#define MRB_PARSER_TOKBUF_MAX (UINT16_MAX-1)
 #define MRB_PARSER_TOKBUF_SIZE 256
 
 /* parser structure */
@@ -119,7 +119,7 @@ struct mrb_parser_state {
 #endif
   mrbc_context *cxt;
   mrb_sym filename_sym;
-  int lineno;
+  uint16_t lineno;
   int column;
 
   enum mrb_lex_state_enum lstate;
@@ -151,8 +151,8 @@ struct mrb_parser_state {
   mrb_ast_node *tree;
 
   mrb_bool no_optimize:1;
-  mrb_bool on_eval:1;
   mrb_bool capture_errors:1;
+  struct RProc *upper;
   struct mrb_parser_message error_buffer[10];
   struct mrb_parser_message warn_buffer[10];
 
@@ -161,6 +161,7 @@ struct mrb_parser_state {
   uint16_t current_filename_index;
 
   struct mrb_jmpbuf* jmp;
+  mrb_ast_node *nvars;
 };
 
 MRB_API struct mrb_parser_state* mrb_parser_new(mrb_state*);
@@ -179,7 +180,15 @@ MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,size_t
 MRB_API struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*);
 MRB_API mrb_value mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c);
 
-/* program load functions */
+/** program load functions 
+* Please note! Currently due to interactions with the GC calling these functions will 
+* leak one RProc object per function call.
+* To prevent this save the current memory arena before calling and restore the arena
+* right after, like so
+* int ai = mrb_gc_arena_save(mrb);
+* mrb_value status = mrb_load_string(mrb, buffer);
+* mrb_gc_arena_restore(mrb, ai);
+*/
 #ifndef MRB_DISABLE_STDIO
 MRB_API mrb_value mrb_load_file(mrb_state*,FILE*);
 MRB_API mrb_value mrb_load_file_cxt(mrb_state*,FILE*, mrbc_context *cxt);
index 4156843..7bdf1c3 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/data.h - Data class
+/**
+** @file mruby/data.h - Data class
 **
 ** See Copyright Notice in mruby.h
 */
@@ -41,7 +41,7 @@ MRB_API struct RData *mrb_data_object_alloc(mrb_state *mrb, struct RClass* klass
 
 #define Data_Make_Struct(mrb,klass,strct,type,sval,data_obj) do { \
   (data_obj) = Data_Wrap_Struct(mrb,klass,type,NULL);\
-  (sval) = mrb_malloc(mrb, sizeof(strct));                     \
+  (sval) = (strct *)mrb_malloc(mrb, sizeof(strct));                     \
   { static const strct zero = { 0 }; *(sval) = zero; };\
   (data_obj)->data = (sval);\
 } while (0)
@@ -63,10 +63,10 @@ MRB_API void *mrb_data_check_get_ptr(mrb_state *mrb, mrb_value, const mrb_data_t
   *(void**)&sval = mrb_data_get_ptr(mrb, obj, type); \
 } while (0)
 
-static inline void
+MRB_INLINE void
 mrb_data_init(mrb_value v, void *ptr, const mrb_data_type *type)
 {
-  mrb_assert(mrb_type(v) == MRB_TT_DATA);
+  mrb_assert(mrb_data_p(v));
   DATA_PTR(v) = ptr;
   DATA_TYPE(v) = type;
 }
index e08c47c..f28dd64 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/debug.h - mruby debug info
+/**
+** @file mruby/debug.h - mruby debug info
 **
 ** See Copyright Notice in mruby.h
 */
index 0234a36..db3e287 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/dump.h - mruby binary dumper (mrbc binary format)
+/**
+** @file mruby/dump.h - mruby binary dumper (mrbc binary format)
 **
 ** See Copyright Notice in mruby.h
 */
 MRB_BEGIN_DECL
 
 #define DUMP_DEBUG_INFO 1
-#define DUMP_ENDIAN_BIG 2
-#define DUMP_ENDIAN_LIL 4
-#define DUMP_ENDIAN_NAT 6
-#define DUMP_ENDIAN_MASK 6
 
 int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
 #ifndef MRB_DISABLE_STDIO
@@ -31,6 +27,7 @@ MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*);
 MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*);
 #endif
 MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
+MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t);
 
 /* dump/load error code
  *
@@ -51,8 +48,7 @@ MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
 
 /* Rite Binary File header */
 #define RITE_BINARY_IDENT              "RITE"
-#define RITE_BINARY_IDENT_LIL          "ETIR"
-#define RITE_BINARY_FORMAT_VER         "0006"
+#define RITE_BINARY_FORMAT_VER         "0007"
 #define RITE_COMPILER_NAME             "MATZ"
 #define RITE_COMPILER_VERSION          "0000"
 
@@ -60,7 +56,6 @@ MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
 
 #define RITE_BINARY_EOF                "END\0"
 #define RITE_SECTION_IREP_IDENT        "IREP"
-#define RITE_SECTION_LINENO_IDENT      "LINE"
 #define RITE_SECTION_DEBUG_IDENT       "DBG\0"
 #define RITE_SECTION_LV_IDENT          "LVAR"
 
@@ -92,10 +87,6 @@ struct rite_section_irep_header {
   uint8_t rite_version[4];    /* Rite Instruction Specification Version */
 };
 
-struct rite_section_lineno_header {
-  RITE_SECTION_HEADER;
-};
-
 struct rite_section_debug_header {
   RITE_SECTION_HEADER;
 };
@@ -110,17 +101,6 @@ struct rite_binary_footer {
   RITE_SECTION_HEADER;
 };
 
-static inline int
-bigendian_p()
-{
-  int i;
-  char *p;
-
-  i = 1;
-  p = (char*)&i;
-  return p[0]?0:1;
-}
-
 static inline size_t
 uint8_to_bin(uint8_t s, uint8_t *bin)
 {
index 237c701..d24b5b0 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/error.h - Exception class
+/**
+** @file mruby/error.h - Exception class
 **
 ** See Copyright Notice in mruby.h
 */
@@ -32,23 +32,51 @@ MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_va
 /* declaration for `fail` method */
 MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value);
 
+#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING)
 struct RBreak {
   MRB_OBJECT_HEADER;
   struct RProc *proc;
   mrb_value val;
 };
+#define mrb_break_value_get(brk) ((brk)->val)
+#define mrb_break_value_set(brk, v) ((brk)->val = v)
+#else
+struct RBreak {
+  MRB_OBJECT_HEADER;
+  struct RProc *proc;
+  union mrb_value_union value;
+};
+#define RBREAK_VALUE_TT_MASK ((1 << 8) - 1)
+static inline mrb_value
+mrb_break_value_get(struct RBreak *brk)
+{
+  mrb_value val;
+  val.value = brk->value;
+  val.tt = (enum mrb_vtype)(brk->flags & RBREAK_VALUE_TT_MASK);
+  return val;
+}
+static inline void
+mrb_break_value_set(struct RBreak *brk, mrb_value val)
+{
+  brk->value = val.value;
+  brk->flags &= ~RBREAK_VALUE_TT_MASK;
+  brk->flags |= val.tt;
+}
+#endif  /* MRB_64BIT || MRB_USE_FLOAT || MRB_NAN_BOXING || MRB_WORD_BOXING */
+#define mrb_break_proc_get(brk) ((brk)->proc)
+#define mrb_break_proc_set(brk, p) ((brk)->proc = p)
 
 /**
  * Protect
  *
- * @mrbgem mruby-error
+ * Implemented in the mruby-error mrbgem
  */
 MRB_API mrb_value mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state);
 
 /**
  * Ensure
  *
- * @mrbgem mruby-error
+ * Implemented in the mruby-error mrbgem
  */
 MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
                              mrb_func_t ensure, mrb_value e_data);
@@ -56,7 +84,7 @@ MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
 /**
  * Rescue
  *
- * @mrbgem mruby-error
+ * Implemented in the mruby-error mrbgem
  */
 MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
                              mrb_func_t rescue, mrb_value r_data);
@@ -64,7 +92,7 @@ MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
 /**
  * Rescue exception
  *
- * @mrbgem mruby-error
+ * Implemented in the mruby-error mrbgem
  */
 MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
                                         mrb_func_t rescue, mrb_value r_data,
index 2a3ff41..4d9fb60 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/gc.h - garbage collector for mruby
+/**
+** @file mruby/gc.h - garbage collector for mruby
 **
 ** See Copyright Notice in mruby.h
 */
index 7e2ed55..0052a11 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/hash.h - Hash class
+/**
+** @file mruby/hash.h - Hash class
 **
 ** See Copyright Notice in mruby.h
 */
@@ -23,7 +23,7 @@ struct RHash {
 #define mrb_hash_ptr(v)    ((struct RHash*)(mrb_ptr(v)))
 #define mrb_hash_value(p)  mrb_obj_value((void*)(p))
 
-MRB_API mrb_value mrb_hash_new_capa(mrb_state*, mrb_int);
+MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa);
 MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash);
 MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
 
@@ -95,7 +95,7 @@ MRB_API mrb_value mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key,
  * @param mrb The mruby state reference.
  * @param hash The target hash.
  * @param key The key to delete.
- * @return The deleted value.
+ * @return The deleted value. This value is not protected from GC. Use `mrb_gc_protect()` if necessary.
  */
 MRB_API mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key);
 
@@ -197,13 +197,6 @@ MRB_API mrb_value mrb_hash_dup(mrb_state *mrb, mrb_value hash);
  */
 MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2);
 
-/* declaration of struct mrb_hash_value */
-/* be careful when you touch the internal */
-typedef struct {
-  mrb_value v;
-  mrb_int n;
-} mrb_hash_value;
-
 /* RHASH_TBL allocates st_table if not available. */
 #define RHASH(obj)   ((struct RHash*)(mrb_ptr(obj)))
 #define RHASH_TBL(h)          (RHASH(h)->ht)
index 027a294..661ef2b 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/irep.h - mrb_irep structure
+/**
+** @file mruby/irep.h - mrb_irep structure
 **
 ** See Copyright Notice in mruby.h
 */
@@ -32,7 +32,7 @@ typedef struct mrb_irep {
   uint16_t nregs;          /* Number of register variables */
   uint8_t flags;
 
-  mrb_code *iseq;
+  const mrb_code *iseq;
   mrb_value *pool;
   mrb_sym *syms;
   struct mrb_irep **reps;
@@ -49,12 +49,34 @@ typedef struct mrb_irep {
 
 MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb);
 
+/** load mruby bytecode functions
+* Please note! Currently due to interactions with the GC calling these functions will
+* leak one RProc object per function call.
+* To prevent this save the current memory arena before calling and restore the arena
+* right after, like so
+* int ai = mrb_gc_arena_save(mrb);
+* mrb_value status = mrb_load_irep(mrb, buffer);
+* mrb_gc_arena_restore(mrb, ai);
+*/
+
 /* @param [const uint8_t*] irep code, expected as a literal */
 MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*);
 
+/*
+ * @param [const void*] irep code
+ * @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted.
+ */
+MRB_API mrb_value mrb_load_irep_buf(mrb_state*, const void*, size_t);
+
 /* @param [const uint8_t*] irep code, expected as a literal */
 MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*);
 
+/*
+ * @param [const void*] irep code
+ * @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted.
+ */
+MRB_API mrb_value mrb_load_irep_buf_cxt(mrb_state*, const void*, size_t, mrbc_context*);
+
 void mrb_irep_free(mrb_state*, struct mrb_irep*);
 void mrb_irep_incref(mrb_state*, struct mrb_irep*);
 void mrb_irep_decref(mrb_state*, struct mrb_irep*);
@@ -68,7 +90,7 @@ struct mrb_insn_data {
   uint8_t c;
 };
 
-struct mrb_insn_data mrb_decode_insn(mrb_code *pc);
+struct mrb_insn_data mrb_decode_insn(const mrb_code *pc);
 
 MRB_END_DECL
 
index 4d2393c..d6b6116 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/istruct.h - Inline structures
+/**
+** @file mruby/istruct.h - Inline structures
 **
 ** See Copyright Notice in mruby.h
 */
@@ -19,12 +19,15 @@ MRB_BEGIN_DECL
 
 #define ISTRUCT_DATA_SIZE (sizeof(void*) * 3)
 
-struct RIstruct {
+struct RIStruct {
   MRB_OBJECT_HEADER;
-  char inline_data[ISTRUCT_DATA_SIZE];
+  union {
+    intptr_t inline_alignment[3];
+    char inline_data[ISTRUCT_DATA_SIZE];
+  };
 };
 
-#define RISTRUCT(obj)         ((struct RIstruct*)(mrb_ptr(obj)))
+#define RISTRUCT(obj)         ((struct RIStruct*)(mrb_ptr(obj)))
 #define ISTRUCT_PTR(obj)      (RISTRUCT(obj)->inline_data)
 
 MRB_INLINE mrb_int mrb_istruct_size()
index 9c40c6b..9f3f1a2 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/khash.c - Hash for mruby
+/**
+** @file mruby/khash.h - Hash for mruby
 **
 ** See Copyright Notice in mruby.h
 */
@@ -73,6 +73,7 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
   void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h);               \
   khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key);           \
   khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret); \
+  void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h);                   \
   void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets); \
   void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x);                \
   kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h);
@@ -95,16 +96,25 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
    __hash_equal: hash comparation function
 */
 #define KHASH_DEFINE(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
-  void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h)                \
+  mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb);                 \
+  int kh_alloc_simple_##name(mrb_state *mrb, kh_##name##_t *h)          \
   {                                                                     \
     khint_t sz = h->n_buckets;                                          \
     size_t len = sizeof(khkey_t) + (kh_is_map ? sizeof(khval_t) : 0);   \
-    uint8_t *p = (uint8_t*)mrb_malloc(mrb, sizeof(uint8_t)*sz/4+len*sz); \
+    uint8_t *p = (uint8_t*)mrb_malloc_simple(mrb, sizeof(uint8_t)*sz/4+len*sz); \
+    if (!p) { return 1; }                                               \
     h->size = h->n_occupied = 0;                                        \
     h->keys = (khkey_t *)p;                                             \
     h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL;     \
     h->ed_flags = p+len*sz;                                             \
     kh_fill_flags(h->ed_flags, 0xaa, sz/4);                             \
+    return 0;                                                           \
+  }                                                                     \
+  void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h)                \
+  {                                                                     \
+    if (kh_alloc_simple_##name(mrb, h)) {                               \
+      mrb_raise_nomemory(mrb);                                          \
+    }                                                                   \
   }                                                                     \
   kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size) {  \
     kh_##name##_t *h = (kh_##name##_t*)mrb_calloc(mrb, 1, sizeof(kh_##name##_t)); \
@@ -112,7 +122,10 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
       size = KHASH_MIN_SIZE;                                            \
     khash_power2(size);                                                 \
     h->n_buckets = size;                                                \
-    kh_alloc_##name(mrb, h);                                            \
+    if (kh_alloc_simple_##name(mrb, h)) {                               \
+      mrb_free(mrb, h);                                                 \
+      mrb_raise_nomemory(mrb);                                          \
+    }                                                                   \
     return h;                                                           \
   }                                                                     \
   kh_##name##_t *kh_init_##name(mrb_state *mrb) {                       \
@@ -171,12 +184,16 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
       mrb_free(mrb, old_keys);                                          \
     }                                                                   \
   }                                                                     \
-  khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
+  void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h)          \
   {                                                                     \
-    khint_t k, del_k, step = 0;                                         \
     if (h->n_occupied >= khash_upper_bound(h)) {                        \
       kh_resize_##name(mrb, h, h->n_buckets*2);                         \
     }                                                                   \
+  }                                                                     \
+  khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
+  {                                                                     \
+    khint_t k, del_k, step = 0;                                         \
+    kh_put_prepare_##name(mrb, h);                                      \
     k = __hash_func(mrb,key) & khash_mask(h);                           \
     del_k = kh_end(h);                                                  \
     while (!__ac_isempty(h->ed_flags, k)) {                             \
@@ -239,6 +256,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
 #define kh_destroy(name, mrb, h) kh_destroy_##name(mrb, h)
 #define kh_clear(name, mrb, h) kh_clear_##name(mrb, h)
 #define kh_resize(name, mrb, h, s) kh_resize_##name(mrb, h, s)
+#define kh_put_prepare(name, mrb, h) kh_put_prepare_##name(mrb, h)
 #define kh_put(name, mrb, h, k) kh_put_##name(mrb, h, k, NULL)
 #define kh_put2(name, mrb, h, k, r) kh_put_##name(mrb, h, k, r)
 #define kh_get(name, mrb, h, k) kh_get_##name(mrb, h, k)
index da9225a..06a33cc 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/numeric.h - Numeric, Integer, Float, Fixnum class
+/**
+** @file mruby/numeric.h - Numeric, Integer, Float, Fixnum class
 **
 ** See Copyright Notice in mruby.h
 */
@@ -23,7 +23,11 @@ MRB_BEGIN_DECL
 #define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int)
 #define FIXABLE(f) TYPED_FIXABLE(f,mrb_int)
 #ifndef MRB_WITHOUT_FLOAT
-#define FIXABLE_FLOAT(f) TYPED_FIXABLE(f,double)
+#ifdef MRB_INT64
+#define FIXABLE_FLOAT(f) ((f)>=-9223372036854775808.0 && (f)<9223372036854775808.0)
+#else
+#define FIXABLE_FLOAT(f) TYPED_FIXABLE(f,mrb_float)
+#endif
 #endif
 
 #ifndef MRB_WITHOUT_FLOAT
@@ -33,13 +37,14 @@ MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base);
 /* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */
 #ifndef MRB_WITHOUT_FLOAT
 MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt);
+MRB_API int mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float f);
 MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x);
+MRB_API mrb_value mrb_int_value(mrb_state *mrb, mrb_float f);
 #endif
 
-mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y);
-mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y);
-mrb_value mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y);
-mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y);
+MRB_API mrb_value mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y);
+MRB_API mrb_value mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y);
+MRB_API mrb_value mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y);
 
 #ifndef __has_builtin
   #define __has_builtin(x) 0
@@ -156,6 +161,36 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
 
 #endif
 
+#ifndef MRB_WITHOUT_FLOAT
+# include <stdint.h>
+# include <float.h>
+
+# define MRB_FLT_RADIX          FLT_RADIX
+
+# ifdef MRB_USE_FLOAT
+#  define MRB_FLT_MANT_DIG      FLT_MANT_DIG
+#  define MRB_FLT_EPSILON       FLT_EPSILON
+#  define MRB_FLT_DIG           FLT_DIG
+#  define MRB_FLT_MIN_EXP       FLT_MIN_EXP
+#  define MRB_FLT_MIN           FLT_MIN
+#  define MRB_FLT_MIN_10_EXP    FLT_MIN_10_EXP
+#  define MRB_FLT_MAX_EXP       FLT_MAX_EXP
+#  define MRB_FLT_MAX           FLT_MAX
+#  define MRB_FLT_MAX_10_EXP    FLT_MAX_10_EXP
+
+# else /* not MRB_USE_FLOAT */
+#  define MRB_FLT_MANT_DIG      DBL_MANT_DIG
+#  define MRB_FLT_EPSILON       DBL_EPSILON
+#  define MRB_FLT_DIG           DBL_DIG
+#  define MRB_FLT_MIN_EXP       DBL_MIN_EXP
+#  define MRB_FLT_MIN           DBL_MIN
+#  define MRB_FLT_MIN_10_EXP    DBL_MIN_10_EXP
+#  define MRB_FLT_MAX_EXP       DBL_MAX_EXP
+#  define MRB_FLT_MAX           DBL_MAX
+#  define MRB_FLT_MAX_10_EXP    DBL_MAX_10_EXP
+# endif /* MRB_USE_FLOAT */
+#endif /* MRB_WITHOUT_FLOAT */
+
 MRB_END_DECL
 
 #endif  /* MRUBY_NUMERIC_H */
index 373e3be..f75e99f 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/object.h - mruby object definition
+/**
+** @file mruby/object.h - mruby object definition
 **
 ** See Copyright Notice in mruby.h
 */
@@ -8,15 +8,14 @@
 #define MRUBY_OBJECT_H
 
 #define MRB_OBJECT_HEADER \
-  enum mrb_vtype tt:8;\
-  uint32_t color:3;\
-  uint32_t flags:21;\
-  struct RClass *c;\
-  struct RBasic *gcnext
+  struct RClass *c;       \
+  struct RBasic *gcnext;  \
+  enum mrb_vtype tt:8;    \
+  uint32_t color:3;       \
+  uint32_t flags:21
 
 #define MRB_FLAG_TEST(obj, flag) ((obj)->flags & (flag))
 
-
 struct RBasic {
   MRB_OBJECT_HEADER;
 };
@@ -26,6 +25,7 @@ struct RBasic {
 #define MRB_FROZEN_P(o) ((o)->flags & MRB_FL_OBJ_IS_FROZEN)
 #define MRB_SET_FROZEN_FLAG(o) ((o)->flags |= MRB_FL_OBJ_IS_FROZEN)
 #define MRB_UNSET_FROZEN_FLAG(o) ((o)->flags &= ~MRB_FL_OBJ_IS_FROZEN)
+#define mrb_frozen_p(o) MRB_FROZEN_P(o)
 
 struct RObject {
   MRB_OBJECT_HEADER;
@@ -33,7 +33,6 @@ struct RObject {
 };
 #define mrb_obj_ptr(v)   ((struct RObject*)(mrb_ptr(v)))
 
-#define mrb_immediate_p(x) (mrb_type(x) < MRB_TT_HAS_BASIC)
 #define mrb_special_const_p(x) mrb_immediate_p(x)
 
 struct RFiber {
index d513ca4..95e6736 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/opcode.h - RiteVM operation codes
+/**
+** @file mruby/opcode.h - RiteVM operation codes
 **
 ** See Copyright Notice in mruby.h
 */
index d645946..e85ee31 100644 (file)
@@ -45,9 +45,9 @@ OPCODE(SETMCNST,   BB)       /* R(a+1)::Syms(b) = R(a) */
 OPCODE(GETUPVAR,   BBB)      /* R(a) = uvget(b,c) */
 OPCODE(SETUPVAR,   BBB)      /* uvset(b,c,R(a)) */
 OPCODE(JMP,        S)        /* pc=a */
-OPCODE(JMPIF,      BS)       /* if R(b) pc=a */
-OPCODE(JMPNOT,     BS)       /* if !R(b) pc=a */
-OPCODE(JMPNIL,     BS)       /* if R(b)==nil pc=a */
+OPCODE(JMPIF,      BS)       /* if R(a) pc=b */
+OPCODE(JMPNOT,     BS)       /* if !R(a) pc=b */
+OPCODE(JMPNIL,     BS)       /* if R(a)==nil pc=b */
 OPCODE(ONERR,      S)        /* rescue_push(a) */
 OPCODE(EXCEPT,     B)        /* R(a) = exc */
 OPCODE(RESCUE,     BB)       /* R(b) = R(a).isa?(R(b)) */
@@ -58,7 +58,7 @@ OPCODE(EPOP,       B)        /* A.times{ensure_pop().call} */
 OPCODE(SENDV,      BB)       /* R(a) = call(R(a),Syms(b),*R(a+1)) */
 OPCODE(SENDVB,     BB)       /* R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) */
 OPCODE(SEND,       BBB)      /* R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) */
-OPCODE(SENDB,      BBB)      /* R(a) = call(R(a),Syms(Bx),R(a+1),...,R(a+c),&R(a+c+1)) */
+OPCODE(SENDB,      BBB)      /* R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1)) */
 OPCODE(CALL,       Z)        /* R(0) = self.call(frame.argc, frame.argv) */
 OPCODE(SUPER,      BB)       /* R(a) = super(R(a+1),... ,R(a+b+1)) */
 OPCODE(ARGARY,     BS)       /* R(a) = argument array (16=m5:r1:m5:d1:lv4) */
@@ -71,9 +71,9 @@ OPCODE(RETURN_BLK, B)        /* return R(a) (in-block return) */
 OPCODE(BREAK,      B)        /* break R(a) */
 OPCODE(BLKPUSH,    BS)       /* R(a) = block (16=m5:r1:m5:d1:lv4) */
 OPCODE(ADD,        B)        /* R(a) = R(a)+R(a+1) */
-OPCODE(ADDI,       BB)       /* R(a) = R(a)+mrb_int(c)  */
+OPCODE(ADDI,       BB)       /* R(a) = R(a)+mrb_int(b) */
 OPCODE(SUB,        B)        /* R(a) = R(a)-R(a+1) */
-OPCODE(SUBI,       BB)       /* R(a) = R(a)-C */
+OPCODE(SUBI,       BB)       /* R(a) = R(a)-mrb_int(b) */
 OPCODE(MUL,        B)        /* R(a) = R(a)*R(a+1) */
 OPCODE(DIV,        B)        /* R(a) = R(a)/R(a+1) */
 OPCODE(EQ,         B)        /* R(a) = R(a)==R(a+1) */
@@ -92,8 +92,8 @@ OPCODE(APOST,      BBB)      /* *R(a),R(a+1)..R(a+c) = R(a)[b..] */
 OPCODE(INTERN,     B)        /* R(a) = intern(R(a)) */
 OPCODE(STRING,     BB)       /* R(a) = str_dup(Lit(b)) */
 OPCODE(STRCAT,     B)        /* str_cat(R(a),R(a+1)) */
-OPCODE(HASH,       BB)       /* R(a) = hash_new(R(a),R(a+1)..R(a+b)) */
-OPCODE(HASHADD,    BB)       /* R(a) = hash_push(R(a),R(a+1)..R(a+b)) */
+OPCODE(HASH,       BB)       /* R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1)) */
+OPCODE(HASHADD,    BB)       /* R(a) = hash_push(R(a),R(a+1)..R(a+b*2)) */
 OPCODE(HASHCAT,    B)        /* R(a) = hash_cat(R(a),R(a+1)) */
 OPCODE(LAMBDA,     BB)       /* R(a) = lambda(SEQ[b],L_LAMBDA) */
 OPCODE(BLOCK,      BB)       /* R(a) = lambda(SEQ[b],L_BLOCK) */
@@ -115,3 +115,4 @@ OPCODE(EXT1,       Z)        /* make 1st operand 16bit */
 OPCODE(EXT2,       Z)        /* make 2nd operand 16bit */
 OPCODE(EXT3,       Z)        /* make 1st and 2nd operands 16bit */
 OPCODE(STOP,       Z)        /* stop VM */
+OPCODE(LOADI16,    BS)       /* R(a) = mrb_int(b) */
index 021f9c1..12013c3 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/proc.h - Proc class
+/**
+** @file mruby/proc.h - Proc class
 **
 ** See Copyright Notice in mruby.h
 */
@@ -22,14 +22,19 @@ struct REnv {
   mrb_sym mid;
 };
 
-/* flags (21bits): 1(shared flag):10(cioff/bidx):10(stack_len) */
-#define MRB_ENV_SET_STACK_LEN(e,len) ((e)->flags = (((e)->flags & ~0x3ff)|((unsigned int)(len) & 0x3ff)))
-#define MRB_ENV_STACK_LEN(e) ((mrb_int)((e)->flags & 0x3ff))
-#define MRB_ENV_STACK_UNSHARED (1<<20)
-#define MRB_ENV_UNSHARE_STACK(e) ((e)->flags |= MRB_ENV_STACK_UNSHARED)
-#define MRB_ENV_STACK_SHARED_P(e) (((e)->flags & MRB_ENV_STACK_UNSHARED) == 0)
-#define MRB_ENV_BIDX(e) (((e)->flags >> 10) & 0x3ff)
-#define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0x3ff<<10))|((unsigned int)(idx) & 0x3ff)<<10))
+/* flags (21bits): 1(close):1(touched):1(heap):8(cioff/bidx):8(stack_len) */
+#define MRB_ENV_SET_LEN(e,len) ((e)->flags = (((e)->flags & ~0xff)|((unsigned int)(len) & 0xff)))
+#define MRB_ENV_LEN(e) ((mrb_int)((e)->flags & 0xff))
+#define MRB_ENV_CLOSED (1<<20)
+#define MRB_ENV_TOUCHED (1<<19)
+#define MRB_ENV_HEAPED (1<<18)
+#define MRB_ENV_CLOSE(e) ((e)->flags |= MRB_ENV_CLOSED)
+#define MRB_ENV_TOUCH(e) ((e)->flags |= MRB_ENV_TOUCHED)
+#define MRB_ENV_HEAP(e) ((e)->flags |= MRB_ENV_HEAPED)
+#define MRB_ENV_HEAP_P(e) ((e)->flags & MRB_ENV_HEAPED)
+#define MRB_ENV_ONSTACK_P(e) (((e)->flags & MRB_ENV_CLOSED) == 0)
+#define MRB_ENV_BIDX(e) (((e)->flags >> 8) & 0xff)
+#define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0xff<<8))|((unsigned int)(idx) & 0xff)<<8))
 
 void mrb_env_unshare(mrb_state*, struct REnv*);
 
@@ -86,38 +91,44 @@ struct RProc *mrb_closure_new(mrb_state*, mrb_irep*);
 MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t);
 MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals);
 void mrb_proc_copy(struct RProc *a, struct RProc *b);
+mrb_int mrb_proc_arity(const struct RProc *p);
 
 /* implementation of #send method */
 mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
 
 /* following functions are defined in mruby-proc-ext so please include it when using */
-MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state*, mrb_func_t, mrb_int, const mrb_value*);
-MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state*, mrb_int);
+MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv);
+MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
 /* old name */
 #define mrb_cfunc_env_get(mrb, idx) mrb_proc_cfunc_env_get(mrb, idx)
 
-#ifdef MRB_METHOD_TABLE_INLINE
+#define MRB_METHOD_FUNC_FL 1
+#define MRB_METHOD_NOARG_FL 2
+#ifndef MRB_METHOD_T_STRUCT
 
-#define MRB_METHOD_FUNC_FL ((uintptr_t)1)
 #define MRB_METHOD_FUNC_P(m) (((uintptr_t)(m))&MRB_METHOD_FUNC_FL)
-#define MRB_METHOD_FUNC(m) ((mrb_func_t)((uintptr_t)(m)&(~MRB_METHOD_FUNC_FL)))
-#define MRB_METHOD_FROM_FUNC(m,fn) ((m)=(mrb_method_t)((struct RProc*)((uintptr_t)(fn)|MRB_METHOD_FUNC_FL)))
-#define MRB_METHOD_FROM_PROC(m,pr) ((m)=(mrb_method_t)(struct RProc*)(pr))
+#define MRB_METHOD_NOARG_P(m) (((uintptr_t)(m))&MRB_METHOD_NOARG_FL)
+#define MRB_METHOD_NOARG_SET(m) ((m)=(mrb_method_t)(((uintptr_t)(m))|MRB_METHOD_NOARG_FL))
+#define MRB_METHOD_FUNC(m) ((mrb_func_t)((uintptr_t)(m)>>2))
+#define MRB_METHOD_FROM_FUNC(m,fn) ((m)=(mrb_method_t)((((uintptr_t)(fn))<<2)|MRB_METHOD_FUNC_FL))
+#define MRB_METHOD_FROM_PROC(m,pr) ((m)=(mrb_method_t)(pr))
 #define MRB_METHOD_PROC_P(m) (!MRB_METHOD_FUNC_P(m))
 #define MRB_METHOD_PROC(m) ((struct RProc*)(m))
 #define MRB_METHOD_UNDEF_P(m) ((m)==0)
 
 #else
 
-#define MRB_METHOD_FUNC_P(m) ((m).func_p)
+#define MRB_METHOD_FUNC_P(m) ((m).flags&MRB_METHOD_FUNC_FL)
+#define MRB_METHOD_NOARG_P(m) ((m).flags&MRB_METHOD_NOARG_FL)
 #define MRB_METHOD_FUNC(m) ((m).func)
-#define MRB_METHOD_FROM_FUNC(m,fn) do{(m).func_p=TRUE;(m).func=(fn);}while(0)
-#define MRB_METHOD_FROM_PROC(m,pr) do{(m).func_p=FALSE;(m).proc=(pr);}while(0)
+#define MRB_METHOD_NOARG_SET(m) do{(m).flags|=MRB_METHOD_NOARG_FL;}while(0)
+#define MRB_METHOD_FROM_FUNC(m,fn) do{(m).flags=MRB_METHOD_FUNC_FL;(m).func=(fn);}while(0)
+#define MRB_METHOD_FROM_PROC(m,pr) do{(m).flags=0;(m).proc=(pr);}while(0)
 #define MRB_METHOD_PROC_P(m) (!MRB_METHOD_FUNC_P(m))
 #define MRB_METHOD_PROC(m) ((m).proc)
 #define MRB_METHOD_UNDEF_P(m) ((m).proc==NULL)
 
-#endif /* MRB_METHOD_TABLE_INLINE */
+#endif /* MRB_METHOD_T_STRUCT */
 
 #define MRB_METHOD_CFUNC_P(m) (MRB_METHOD_FUNC_P(m)?TRUE:(MRB_METHOD_PROC(m)?(MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m))):FALSE))
 #define MRB_METHOD_CFUNC(m) (MRB_METHOD_FUNC_P(m)?MRB_METHOD_FUNC(m):((MRB_METHOD_PROC(m)&&MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m)))?MRB_PROC_CFUNC(MRB_METHOD_PROC(m)):NULL))
index b562699..fea700c 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/range.h - Range class
+/**
+** @file mruby/range.h - Range class
 **
 ** See Copyright Notice in mruby.h
 */
@@ -14,7 +14,7 @@
  */
 MRB_BEGIN_DECL
 
-#if defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING)
+#if defined(MRB_NAN_BOXING) && defined(MRB_64BIT) || defined(MRB_WORD_BOXING)
 # define MRB_RANGE_EMBED
 #endif
 
@@ -64,7 +64,13 @@ MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value range);
  */
 MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, mrb_bool exclude);
 
-MRB_API mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc);
+enum mrb_range_beg_len {
+  MRB_RANGE_TYPE_MISMATCH = 0,  /* (failure) not range */
+  MRB_RANGE_OK = 1,             /* (success) range */
+  MRB_RANGE_OUT = 2             /* (failure) out of range */
+};
+
+MRB_API enum mrb_range_beg_len mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc);
 mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int));
 void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r);
 
index 1d09d06..2d48019 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/re.h - Regexp class
+/**
+** @file mruby/re.h - Regexp class
 **
 ** See Copyright Notice in mruby.h
 */
index 0b90deb..93c94ef 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/string.h - String class
+/**
+** @file mruby/string.h - String class
 **
 ** See Copyright Notice in mruby.h
 */
@@ -16,23 +16,30 @@ MRB_BEGIN_DECL
 
 extern const char mrb_digitmap[];
 
-#define RSTRING_EMBED_LEN_MAX ((mrb_int)(sizeof(void*) * 3 - 1))
+#define RSTRING_EMBED_LEN_MAX \
+  ((mrb_int)(sizeof(void*) * 3 + sizeof(void*) - 32 / CHAR_BIT - 1))
 
 struct RString {
   MRB_OBJECT_HEADER;
   union {
     struct {
-      mrb_int len;
+      mrb_ssize len;
       union {
-        mrb_int capa;
+        mrb_ssize capa;
         struct mrb_shared_string *shared;
         struct RString *fshared;
       } aux;
       char *ptr;
     } heap;
-    char ary[RSTRING_EMBED_LEN_MAX + 1];
   } as;
 };
+struct RStringEmbed {
+  MRB_OBJECT_HEADER;
+  char ary[];
+};
+
+#define RSTR_SET_TYPE_FLAG(s, type) (RSTR_UNSET_TYPE_FLAG(s), (s)->flags |= MRB_STR_##type)
+#define RSTR_UNSET_TYPE_FLAG(s) ((s)->flags &= ~(MRB_STR_TYPE_MASK|MRB_STR_EMBED_LEN_MASK))
 
 #define RSTR_EMBED_P(s) ((s)->flags & MRB_STR_EMBED)
 #define RSTR_SET_EMBED_FLAG(s) ((s)->flags |= MRB_STR_EMBED)
@@ -47,12 +54,15 @@ struct RString {
     RSTR_SET_EMBED_LEN((s),(n));\
   }\
   else {\
-    (s)->as.heap.len = (mrb_int)(n);\
+    (s)->as.heap.len = (mrb_ssize)(n);\
   }\
 } while (0)
+#define RSTR_EMBED_PTR(s) (((struct RStringEmbed*)(s))->ary)
 #define RSTR_EMBED_LEN(s)\
   (mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT)
-#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? (s)->as.ary : (s)->as.heap.ptr)
+#define RSTR_EMBEDDABLE_P(len) ((len) <= RSTRING_EMBED_LEN_MAX)
+
+#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_PTR(s) : (s)->as.heap.ptr)
 #define RSTR_LEN(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_LEN(s) : (s)->as.heap.len)
 #define RSTR_CAPA(s) (RSTR_EMBED_P(s) ? RSTRING_EMBED_LEN_MAX : (s)->as.heap.aux.capa)
 
@@ -68,10 +78,24 @@ struct RString {
 #define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE)
 #define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE)
 
+#ifdef MRB_UTF8_STRING
+# define RSTR_ASCII_P(s) ((s)->flags & MRB_STR_ASCII)
+# define RSTR_SET_ASCII_FLAG(s) ((s)->flags |= MRB_STR_ASCII)
+# define RSTR_UNSET_ASCII_FLAG(s) ((s)->flags &= ~MRB_STR_ASCII)
+# define RSTR_WRITE_ASCII_FLAG(s, v) (RSTR_UNSET_ASCII_FLAG(s), (s)->flags |= v)
+# define RSTR_COPY_ASCII_FLAG(dst, src) RSTR_WRITE_ASCII_FLAG(dst, RSTR_ASCII_P(src))
+#else
+# define RSTR_ASCII_P(s) (void)0
+# define RSTR_SET_ASCII_FLAG(s) (void)0
+# define RSTR_UNSET_ASCII_FLAG(s) (void)0
+# define RSTR_WRITE_ASCII_FLAG(s, v) (void)0
+# define RSTR_COPY_ASCII_FLAG(dst, src) (void)0
+#endif
+
 #define RSTR_POOL_P(s) ((s)->flags & MRB_STR_POOL)
 #define RSTR_SET_POOL_FLAG(s) ((s)->flags |= MRB_STR_POOL)
 
-/*
+/**
  * Returns a pointer from a Ruby string
  */
 #define mrb_str_ptr(s)       ((struct RString*)(mrb_ptr(s)))
@@ -82,32 +106,38 @@ struct RString {
 #define RSTRING_CAPA(s)      RSTR_CAPA(RSTRING(s))
 #define RSTRING_END(s)       (RSTRING_PTR(s) + RSTRING_LEN(s))
 MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
+#define RSTRING_CSTR(mrb,s)  mrb_string_cstr(mrb, s)
 
 #define MRB_STR_SHARED    1
 #define MRB_STR_FSHARED   2
 #define MRB_STR_NOFREE    4
-#define MRB_STR_POOL      8
-#define MRB_STR_NO_UTF   16
-#define MRB_STR_EMBED    32
-#define MRB_STR_EMBED_LEN_MASK 0x7c0
+#define MRB_STR_EMBED     8  /* type flags up to here */
+#define MRB_STR_POOL     16  /* status flags from here */
+#define MRB_STR_ASCII    32
 #define MRB_STR_EMBED_LEN_SHIFT 6
+#define MRB_STR_EMBED_LEN_BIT 5
+#define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT)
+#define MRB_STR_TYPE_MASK (MRB_STR_POOL - 1)
+
 
 void mrb_gc_free_str(mrb_state*, struct RString*);
-MRB_API void mrb_str_modify(mrb_state*, struct RString*);
 
-/*
+MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s);
+/* mrb_str_modify() with keeping ASCII flag if set */
+MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s);
+
+/**
  * Finds the index of a substring in a string
  */
-MRB_API mrb_int mrb_str_index(mrb_state*, mrb_value, const char*, mrb_int, mrb_int);
+MRB_API mrb_int mrb_str_index(mrb_state *mrb, mrb_value str, const char *p, mrb_int len, mrb_int offset);
 #define mrb_str_index_lit(mrb, str, lit, off) mrb_str_index(mrb, str, lit, mrb_strlen_lit(lit), off);
 
-/*
+/**
  * Appends self to other. Returns self as a concatenated string.
  *
  *
- *  Example:
+ * Example:
  *
- *     !!!c
  *     int
  *     main(int argc,
  *          char **argv)
@@ -129,32 +159,30 @@ MRB_API mrb_int mrb_str_index(mrb_state*, mrb_value, const char*, mrb_int, mrb_i
  *       // Concatenates str2 to str1.
  *       mrb_str_concat(mrb, str1, str2);
  *
- *      // Prints new Concatenated Ruby string.
- *      mrb_p(mrb, str1);
- *
- *      mrb_close(mrb);
- *      return 0;
- *    }
+ *       // Prints new Concatenated Ruby string.
+ *       mrb_p(mrb, str1);
  *
+ *       mrb_close(mrb);
+ *       return 0;
+ *     } 
  *
- *  Result:
+ * Result:
  *
  *     => "abcdef"
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] self String to concatenate.
- * @param [mrb_value] other String to append to self.
+ * @param mrb The current mruby state.
+ * @param self String to concatenate.
+ * @param other String to append to self.
  * @return [mrb_value] Returns a new String appending other to self.
  */
-MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value);
+MRB_API void mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other);
 
-/*
+/**
  * Adds two strings together.
  *
  *
- *  Example:
+ * Example:
  *
- *     !!!c
  *     int
  *     main(int argc,
  *          char **argv)
@@ -181,52 +209,51 @@ MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value);
  *       // Concatenates both Ruby strings.
  *       c = mrb_str_plus(mrb, a, b);
  *
- *      // Prints new Concatenated Ruby string.
- *      mrb_p(mrb, c);
+ *       // Prints new Concatenated Ruby string.
+ *       mrb_p(mrb, c);
  *
- *      mrb_close(mrb);
- *      return 0;
- *    }
+ *       mrb_close(mrb);
+ *       return 0;
+ *     }
  *
  *
- *  Result:
+ * Result:
  *
  *     => "abc"  # First string
  *     => "def"  # Second string
  *     => "abcdef" # First & Second concatenated.
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] a First string to concatenate.
- * @param [mrb_value] b Second string to concatenate.
+ * @param mrb The current mruby state.
+ * @param a First string to concatenate.
+ * @param b Second string to concatenate.
  * @return [mrb_value] Returns a new String containing a concatenated to b.
  */
-MRB_API mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value);
+MRB_API mrb_value mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b);
 
-/*
+/**
  * Converts pointer into a Ruby string.
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [void*] p The pointer to convert to Ruby string.
+ * @param mrb The current mruby state.
+ * @param p The pointer to convert to Ruby string.
  * @return [mrb_value] Returns a new Ruby String.
  */
-MRB_API mrb_value mrb_ptr_to_str(mrb_state *, void*);
+MRB_API mrb_value mrb_ptr_to_str(mrb_state *mrb, void *p);
 
-/*
+/**
  * Returns an object as a Ruby string.
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] obj An object to return as a Ruby string.
+ * @param mrb The current mruby state.
+ * @param obj An object to return as a Ruby string.
  * @return [mrb_value] An object as a Ruby string.
  */
 MRB_API mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj);
 
-/*
+/**
  * Resizes the string's length. Returns the amount of characters
  * in the specified by len.
  *
  * Example:
  *
- *     !!!c
  *     int
  *     main(int argc,
  *          char **argv)
@@ -251,21 +278,20 @@ MRB_API mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj);
  *
  * Result:
  *
- *     => "Hello"
+ *      => "Hello"
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] str The Ruby string to resize.
- * @param [mrb_value] len The length.
+ * @param mrb The current mruby state.
+ * @param str The Ruby string to resize.
+ * @param len The length.
  * @return [mrb_value] An object as a Ruby string.
  */
 MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len);
 
-/*
+/**
  * Returns a sub string.
  *
- *  Example:
+ * Example:
  *
- *     !!!c
  *     int
  *     main(int argc,
  *     char const **argv)
@@ -291,24 +317,24 @@ MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len);
  *       return 0;
  *     }
  *
- *  Result:
+ * Result:
  *
  *     => "He"
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] str Ruby string.
- * @param [mrb_int] beg The beginning point of the sub-string.
- * @param [mrb_int] len The end point of the sub-string.
+ * @param mrb The current mruby state.
+ * @param str Ruby string.
+ * @param beg The beginning point of the sub-string.
+ * @param len The end point of the sub-string.
  * @return [mrb_value] An object as a Ruby sub-string.
  */
 MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
 
-/*
+/**
  * Returns a Ruby string type.
  *
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] str Ruby string.
+ * @param mrb The current mruby state.
+ * @param str Ruby string.
  * @return [mrb_value] A Ruby string.
  */
 MRB_API mrb_value mrb_ensure_string_type(mrb_state *mrb, mrb_value str);
@@ -320,33 +346,30 @@ MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str);
 MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa);
 MRB_API mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa);
 
-MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr);
+/* NULL terminated C string from mrb_value */
+MRB_API const char *mrb_string_cstr(mrb_state *mrb, mrb_value str);
+/* NULL terminated C string from mrb_value; `str` will be updated */
+MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *str);
+/* obslete: use RSTRING_PTR() */
 MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value str);
-/*
- * Returns the length of the Ruby string.
- *
- *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] str Ruby string.
- * @return [mrb_int] The length of the passed in Ruby string.
- */
+/* obslete: use RSTRING_LEN() */
 MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value str);
 
-/*
+/**
  * Duplicates a string object.
  *
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] str Ruby string.
+ * @param mrb The current mruby state.
+ * @param str Ruby string.
  * @return [mrb_value] Duplicated Ruby string.
  */
 MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str);
 
-/*
+/**
  * Returns a symbol from a passed in Ruby string.
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] self Ruby string.
+ * @param mrb The current mruby state.
+ * @param self Ruby string.
  * @return [mrb_value] A symbol.
  */
 MRB_API mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self);
@@ -356,40 +379,40 @@ MRB_API mrb_value mrb_cstr_to_inum(mrb_state *mrb, const char *s, mrb_int base,
 MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck);
 MRB_API double mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck);
 
-/*
+/**
  * Returns a converted string type.
  * For type checking, non converting `mrb_to_str` is recommended.
  */
 MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
 
-/*
+/**
  * Returns true if the strings match and false if the strings don't match.
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] str1 Ruby string to compare.
- * @param [mrb_value] str2 Ruby string to compare.
+ * @param mrb The current mruby state.
+ * @param str1 Ruby string to compare.
+ * @param str2 Ruby string to compare.
  * @return [mrb_value] boolean value.
  */
 MRB_API mrb_bool mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
 
-/*
- * Returns a concated string comprised of a Ruby string and a C string.
+/**
+ * Returns a concatenated string comprised of a Ruby string and a C string.
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] str Ruby string.
- * @param [const char *] ptr A C string.
- * @param [size_t] len length of C string.
+ * @param mrb The current mruby state.
+ * @param str Ruby string.
+ * @param ptr A C string.
+ * @param len length of C string.
  * @return [mrb_value] A Ruby string.
  * @see mrb_str_cat_cstr
  */
 MRB_API mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len);
 
-/*
- * Returns a concated string comprised of a Ruby string and a C string.
+/**
+ * Returns a concatenated string comprised of a Ruby string and a C string.
  *
- * @param [mrb_state] mrb The current mruby state.
- * @param [mrb_value] str Ruby string.
- * @param [const char *] ptr A C string.
+ * @param mrb The current mruby state.
+ * @param str Ruby string.
+ * @param ptr A C string.
  * @return [mrb_value] A Ruby string.
  * @see mrb_str_cat
  */
@@ -397,17 +420,17 @@ MRB_API mrb_value mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *pt
 MRB_API mrb_value mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2);
 #define mrb_str_cat_lit(mrb, str, lit) mrb_str_cat(mrb, str, lit, mrb_strlen_lit(lit))
 
-/*
+/**
  * Adds str2 to the end of str1.
  */
 MRB_API mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2);
 
-/*
+/**
  * Returns 0 if both Ruby strings are equal. Returns a value < 0 if Ruby str1 is less than Ruby str2. Returns a value > 0 if Ruby str2 is greater than Ruby str1.
  */
 MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
 
-/*
+/**
  * Returns a newly allocated C string from a Ruby string.
  * This is an utility function to pass a Ruby string to C library functions.
  *
@@ -418,31 +441,32 @@ MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
  * - Caller can modify returned string without affecting Ruby string
  *   (e.g. it can be used for mkstemp(3)).
  *
- * @param [mrb_state *] mrb The current mruby state.
- * @param [mrb_value] str Ruby string. Must be an instance of String.
+ * @param mrb The current mruby state.
+ * @param str Ruby string. Must be an instance of String.
  * @return [char *] A newly allocated C string.
  */
 MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
 
-mrb_value mrb_str_pool(mrb_state *mrb, mrb_value str);
+mrb_value mrb_str_pool(mrb_state *mrb, const char *s, mrb_int len, mrb_bool nofree);
 uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str);
 mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
 
-/*
+/**
  * Returns a printable version of str, surrounded by quote marks, with special characters escaped.
  */
 mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
 
-void mrb_noregexp(mrb_state *mrb, mrb_value self);
-void mrb_regexp_check(mrb_state *mrb, mrb_value obj);
-
 /* For backward compatibility */
 #define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr)
 #define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len)
 #define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2)
 
+mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp);
+mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
+
 #ifdef MRB_UTF8_STRING
-mrb_int mrb_utf8_len(const char *str, mrb_int byte_len);
+mrb_int mrb_utf8len(const char *str, const char *end);
+mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len);
 #endif
 
 MRB_END_DECL
index 4a1fd8d..1f1298d 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/throw.h - mruby exception throwing handler
+/**
+** @file mruby/throw.h - mruby exception throwing handler
 **
 ** See Copyright Notice in mruby.h
 */
index 1ed2085..473774b 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/value.h - mruby value definitions
+/**
+** @file mruby/value.h - mruby value definitions
 **
 ** See Copyright Notice in mruby.h
 */
@@ -9,28 +9,43 @@
 
 #include "common.h"
 
-/**
+/*
  * MRuby Value definition functions and macros.
  */
 MRB_BEGIN_DECL
 
+/**
+ * mruby Symbol.
+ * @class mrb_sym
+ *
+ * You can create an mrb_sym by simply using mrb_str_intern() or mrb_intern_cstr()
+ */
 typedef uint32_t mrb_sym;
+
+/**
+ * mruby Boolean.
+ * @class mrb_bool
+ *
+ *
+ * Used internally to represent boolean. Can be TRUE or FALSE.
+ * Not to be confused with Ruby's boolean classes, which can be
+ * obtained using mrb_false_value() and mrb_true_value()
+ */
 typedef uint8_t mrb_bool;
 struct mrb_state;
 
-#if defined(MRB_INT16) && defined(MRB_INT64)
-# error "You can't define MRB_INT16 and MRB_INT64 at the same time."
-#endif
-
 #if defined _MSC_VER && _MSC_VER < 1800
 # define PRIo64 "llo"
 # define PRId64 "lld"
+# define PRIu64 "llu"
 # define PRIx64 "llx"
 # define PRIo16 "ho"
 # define PRId16 "hd"
+# define PRIu16 "hu"
 # define PRIx16 "hx"
 # define PRIo32 "o"
 # define PRId32 "d"
+# define PRIu32 "u"
 # define PRIx32 "x"
 #else
 # include <inttypes.h>
@@ -44,14 +59,6 @@ struct mrb_state;
 # define MRB_PRIo PRIo64
 # define MRB_PRId PRId64
 # define MRB_PRIx PRIx64
-#elif defined(MRB_INT16)
-  typedef int16_t mrb_int;
-# define MRB_INT_BIT 16
-# define MRB_INT_MIN (INT16_MIN>>MRB_FIXNUM_SHIFT)
-# define MRB_INT_MAX (INT16_MAX>>MRB_FIXNUM_SHIFT)
-# define MRB_PRIo PRIo16
-# define MRB_PRId PRId16
-# define MRB_PRIx PRIx16
 #else
   typedef int32_t mrb_int;
 # define MRB_INT_BIT 32
@@ -62,6 +69,11 @@ struct mrb_state;
 # define MRB_PRIx PRIx32
 #endif
 
+#ifdef MRB_ENDIAN_BIG
+# define MRB_ENDIAN_LOHI(a,b) a b
+#else
+# define MRB_ENDIAN_LOHI(a,b) b a
+#endif
 
 #ifndef MRB_WITHOUT_FLOAT
 MRB_API double mrb_float_read(const char*, char**);
@@ -73,9 +85,6 @@ MRB_API double mrb_float_read(const char*, char**);
 #endif
 
 #if defined _MSC_VER && _MSC_VER < 1900
-# ifndef __cplusplus
-#  define inline __inline
-# endif
 # include <stdarg.h>
 MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg);
 MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...);
@@ -94,32 +103,31 @@ static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000;
 #endif
 
 enum mrb_vtype {
-  MRB_TT_FALSE = 0,   /*   0 */
-  MRB_TT_FREE,        /*   1 */
-  MRB_TT_TRUE,        /*   2 */
-  MRB_TT_FIXNUM,      /*   3 */
-  MRB_TT_SYMBOL,      /*   4 */
-  MRB_TT_UNDEF,       /*   5 */
-  MRB_TT_FLOAT,       /*   6 */
-  MRB_TT_CPTR,        /*   7 */
-  MRB_TT_OBJECT,      /*   8 */
-  MRB_TT_CLASS,       /*   9 */
-  MRB_TT_MODULE,      /*  10 */
-  MRB_TT_ICLASS,      /*  11 */
-  MRB_TT_SCLASS,      /*  12 */
-  MRB_TT_PROC,        /*  13 */
-  MRB_TT_ARRAY,       /*  14 */
-  MRB_TT_HASH,        /*  15 */
-  MRB_TT_STRING,      /*  16 */
-  MRB_TT_RANGE,       /*  17 */
-  MRB_TT_EXCEPTION,   /*  18 */
-  MRB_TT_FILE,        /*  19 */
-  MRB_TT_ENV,         /*  20 */
-  MRB_TT_DATA,        /*  21 */
-  MRB_TT_FIBER,       /*  22 */
-  MRB_TT_ISTRUCT,     /*  23 */
-  MRB_TT_BREAK,       /*  24 */
-  MRB_TT_MAXDEFINE    /*  25 */
+  MRB_TT_FALSE = 0,
+  MRB_TT_TRUE,
+  MRB_TT_FLOAT,
+  MRB_TT_FIXNUM,
+  MRB_TT_SYMBOL,
+  MRB_TT_UNDEF,
+  MRB_TT_CPTR,
+  MRB_TT_FREE,
+  MRB_TT_OBJECT,
+  MRB_TT_CLASS,
+  MRB_TT_MODULE,
+  MRB_TT_ICLASS,
+  MRB_TT_SCLASS,
+  MRB_TT_PROC,
+  MRB_TT_ARRAY,
+  MRB_TT_HASH,
+  MRB_TT_STRING,
+  MRB_TT_RANGE,
+  MRB_TT_EXCEPTION,
+  MRB_TT_ENV,
+  MRB_TT_DATA,
+  MRB_TT_FIBER,
+  MRB_TT_ISTRUCT,
+  MRB_TT_BREAK,
+  MRB_TT_MAXDEFINE
 };
 
 #include <mruby/object.h>
@@ -140,6 +148,13 @@ typedef void mrb_value;
 
 #endif
 
+#if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_64BIT))
+struct RCptr {
+  MRB_OBJECT_HEADER;
+  void *p;
+};
+#endif
+
 #if defined(MRB_NAN_BOXING)
 #include "boxing_nan.h"
 #elif defined(MRB_WORD_BOXING)
@@ -148,36 +163,106 @@ typedef void mrb_value;
 #include "boxing_no.h"
 #endif
 
+#define MRB_SYMBOL_BIT (sizeof(mrb_sym) * CHAR_BIT - MRB_SYMBOL_SHIFT)
+#define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SYMBOL_SHIFT)
+
+#if INTPTR_MAX < MRB_INT_MAX
+  typedef intptr_t mrb_ssize;
+# define MRB_SSIZE_MAX (INTPTR_MAX>>MRB_FIXNUM_SHIFT)
+#else
+  typedef mrb_int mrb_ssize;
+# define MRB_SSIZE_MAX MRB_INT_MAX
+#endif
+
+#ifndef mrb_immediate_p
+#define mrb_immediate_p(o) (mrb_type(o) < MRB_TT_FREE)
+#endif
 #ifndef mrb_fixnum_p
 #define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
 #endif
+#ifndef mrb_symbol_p
+#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
+#endif
 #ifndef mrb_undef_p
 #define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF)
 #endif
 #ifndef mrb_nil_p
 #define mrb_nil_p(o)  (mrb_type(o) == MRB_TT_FALSE && !mrb_fixnum(o))
 #endif
-#ifndef mrb_bool
-#define mrb_bool(o)   (mrb_type(o) != MRB_TT_FALSE)
+#ifndef mrb_false_p
+#define mrb_false_p(o) (mrb_type(o) == MRB_TT_FALSE && !!mrb_fixnum(o))
 #endif
-#if !defined(MRB_SYMBOL_BITSIZE)
-#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT)
-#define MRB_SYMBOL_MAX      UINT32_MAX
+#ifndef mrb_true_p
+#define mrb_true_p(o)  (mrb_type(o) == MRB_TT_TRUE)
 #endif
 #ifndef MRB_WITHOUT_FLOAT
+#ifndef mrb_float_p
 #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
 #endif
-#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
+#endif
+#ifndef mrb_array_p
 #define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
+#endif
+#ifndef mrb_string_p
 #define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
+#endif
+#ifndef mrb_hash_p
 #define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH)
+#endif
+#ifndef mrb_cptr_p
 #define mrb_cptr_p(o) (mrb_type(o) == MRB_TT_CPTR)
+#endif
+#ifndef mrb_exception_p
 #define mrb_exception_p(o) (mrb_type(o) == MRB_TT_EXCEPTION)
+#endif
+#ifndef mrb_free_p
+#define mrb_free_p(o) (mrb_type(o) == MRB_TT_FREE)
+#endif
+#ifndef mrb_object_p
+#define mrb_object_p(o) (mrb_type(o) == MRB_TT_OBJECT)
+#endif
+#ifndef mrb_class_p
+#define mrb_class_p(o) (mrb_type(o) == MRB_TT_CLASS)
+#endif
+#ifndef mrb_module_p
+#define mrb_module_p(o) (mrb_type(o) == MRB_TT_MODULE)
+#endif
+#ifndef mrb_iclass_p
+#define mrb_iclass_p(o) (mrb_type(o) == MRB_TT_ICLASS)
+#endif
+#ifndef mrb_sclass_p
+#define mrb_sclass_p(o) (mrb_type(o) == MRB_TT_SCLASS)
+#endif
+#ifndef mrb_proc_p
+#define mrb_proc_p(o) (mrb_type(o) == MRB_TT_PROC)
+#endif
+#ifndef mrb_range_p
+#define mrb_range_p(o) (mrb_type(o) == MRB_TT_RANGE)
+#endif
+#ifndef mrb_env_p
+#define mrb_env_p(o) (mrb_type(o) == MRB_TT_ENV)
+#endif
+#ifndef mrb_data_p
+#define mrb_data_p(o) (mrb_type(o) == MRB_TT_DATA)
+#endif
+#ifndef mrb_fiber_p
+#define mrb_fiber_p(o) (mrb_type(o) == MRB_TT_FIBER)
+#endif
+#ifndef mrb_istruct_p
+#define mrb_istruct_p(o) (mrb_type(o) == MRB_TT_ISTRUCT)
+#endif
+#ifndef mrb_break_p
+#define mrb_break_p(o) (mrb_type(o) == MRB_TT_BREAK)
+#endif
+#ifndef mrb_bool
+#define mrb_bool(o)   (mrb_type(o) != MRB_TT_FALSE)
+#endif
 #define mrb_test(o)   mrb_bool(o)
-MRB_API mrb_bool mrb_regexp_p(struct mrb_state*, mrb_value);
 
-/*
+/**
  * Returns a float in Ruby.
+ *
+ * Takes a float and boxes it into an mrb_value
  */
 #ifndef MRB_WITHOUT_FLOAT
 MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
@@ -189,7 +274,7 @@ MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
 }
 #endif
 
-static inline mrb_value
+MRB_INLINE mrb_value
 mrb_cptr_value(struct mrb_state *mrb, void *p)
 {
   mrb_value v;
@@ -198,8 +283,10 @@ mrb_cptr_value(struct mrb_state *mrb, void *p)
   return v;
 }
 
-/*
+/**
  * Returns a fixnum in Ruby.
+ *
+ * Takes an integer and boxes it into an mrb_value
  */
 MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i)
 {
@@ -208,7 +295,7 @@ MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i)
   return v;
 }
 
-static inline mrb_value
+MRB_INLINE mrb_value
 mrb_symbol_value(mrb_sym i)
 {
   mrb_value v;
@@ -216,7 +303,7 @@ mrb_symbol_value(mrb_sym i)
   return v;
 }
 
-static inline mrb_value
+MRB_INLINE mrb_value
 mrb_obj_value(void *p)
 {
   mrb_value v;
@@ -226,8 +313,7 @@ mrb_obj_value(void *p)
   return v;
 }
 
-
-/*
+/**
  * Get a nil mrb_value object.
  *
  * @return
@@ -240,7 +326,7 @@ MRB_INLINE mrb_value mrb_nil_value(void)
   return v;
 }
 
-/*
+/**
  * Returns false in Ruby.
  */
 MRB_INLINE mrb_value mrb_false_value(void)
@@ -250,7 +336,7 @@ MRB_INLINE mrb_value mrb_false_value(void)
   return v;
 }
 
-/*
+/**
  * Returns true in Ruby.
  */
 MRB_INLINE mrb_value mrb_true_value(void)
@@ -260,7 +346,7 @@ MRB_INLINE mrb_value mrb_true_value(void)
   return v;
 }
 
-static inline mrb_value
+MRB_INLINE mrb_value
 mrb_bool_value(mrb_bool boolean)
 {
   mrb_value v;
@@ -268,7 +354,7 @@ mrb_bool_value(mrb_bool boolean)
   return v;
 }
 
-static inline mrb_value
+MRB_INLINE mrb_value
 mrb_undef_value(void)
 {
   mrb_value v;
@@ -276,34 +362,25 @@ mrb_undef_value(void)
   return v;
 }
 
-#ifdef MRB_USE_ETEXT_EDATA
-#if (defined(__APPLE__) && defined(__MACH__))
-#include <mach-o/getsect.h>
-static inline mrb_bool
-mrb_ro_data_p(const char *p)
-{
-  return (const char*)get_etext() < p && p < (const char*)get_edata();
-}
-#else
-extern char _etext[];
-#ifdef MRB_NO_INIT_ARRAY_START
-extern char _edata[];
+#if defined(MRB_USE_ETEXT_EDATA) && !defined(MRB_USE_LINK_TIME_RO_DATA_P)
+# ifdef __GNUC__
+#  warning MRB_USE_ETEXT_EDATA is deprecated. Define MRB_USE_LINK_TIME_RO_DATA_P instead.
+# endif
+# define MRB_USE_LINK_TIME_RO_DATA_P
+#endif
 
-static inline mrb_bool
-mrb_ro_data_p(const char *p)
-{
-  return _etext < p && p < _edata;
-}
-#else
+#if defined(MRB_USE_CUSTOM_RO_DATA_P)
+/* If you define `MRB_USE_CUSTOM_RO_DATA_P`, you must implement `mrb_ro_data_p()`. */
+mrb_bool mrb_ro_data_p(const char *p);
+#elif defined(MRB_USE_LINK_TIME_RO_DATA_P)
+extern char __ehdr_start[];
 extern char __init_array_start[];
 
 static inline mrb_bool
 mrb_ro_data_p(const char *p)
 {
-  return _etext < p && p < (char*)&__init_array_start;
+  return __ehdr_start < p && p < __init_array_start;
 }
-#endif
-#endif
 #else
 # define mrb_ro_data_p(p) FALSE
 #endif
index ba60379..6e918cf 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/variable.h - mruby variables
+/**
+** @file mruby/variable.h - mruby variables
 **
 ** See Copyright Notice in mruby.h
 */
@@ -97,18 +97,15 @@ MRB_API void mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value val);
  *
  * Example:
  *
- *     !!!ruby
  *     # Ruby style
  *     $value = nil
  *
- *     !!!c
  *     // C style
  *     mrb_sym sym = mrb_intern_lit(mrb, "$value");
  *     mrb_gv_remove(mrb, sym);
  *
  * @param mrb The mruby state reference
  * @param sym The name of the global variable
- * @param val The value of the global variable
  */
 MRB_API void mrb_gv_remove(mrb_state *mrb, mrb_sym sym);
 
@@ -117,6 +114,7 @@ MRB_API void mrb_mod_cv_set(mrb_state *mrb, struct RClass * c, mrb_sym sym, mrb_
 MRB_API void mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v);
 MRB_API mrb_bool mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym);
 mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*);
+void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
 mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod);
 mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self);
 mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value);
index e776373..f52cb3f 100644 (file)
@@ -1,5 +1,5 @@
-/*
-** mruby/version.h - mruby version definition
+/**
+** @file mruby/version.h - mruby version definition
 **
 ** See Copyright Notice in mruby.h
 */
@@ -42,12 +42,12 @@ MRB_BEGIN_DECL
 /*
  * Minor release version number.
  */
-#define MRUBY_RELEASE_MINOR 0
+#define MRUBY_RELEASE_MINOR 1
 
 /*
  * Tiny release version number.
  */
-#define MRUBY_RELEASE_TEENY 1
+#define MRUBY_RELEASE_TEENY 2
 
 /*
  * The mruby version.
@@ -62,22 +62,36 @@ MRB_BEGIN_DECL
 /*
  * Release year.
  */
-#define MRUBY_RELEASE_YEAR 2019
+#define MRUBY_RELEASE_YEAR 2020
 
 /*
  * Release month.
  */
-#define MRUBY_RELEASE_MONTH 4
+#define MRUBY_RELEASE_MONTH 8
 
 /*
  * Release day.
  */
-#define MRUBY_RELEASE_DAY 4
+#define MRUBY_RELEASE_DAY 6
 
 /*
  * Release date as a string.
  */
-#define MRUBY_RELEASE_DATE MRB_STRINGIZE(MRUBY_RELEASE_YEAR) "-" MRB_STRINGIZE(MRUBY_RELEASE_MONTH) "-" MRB_STRINGIZE(MRUBY_RELEASE_DAY)
+#define MRUBY_RELEASE_DATE    \
+  MRUBY_RELEASE_YEAR_STR "-"  \
+  MRUBY_RELEASE_MONTH_STR "-" \
+  MRUBY_RELEASE_DAY_STR
+#define MRUBY_RELEASE_YEAR_STR MRB_STRINGIZE(MRUBY_RELEASE_YEAR)
+#if MRUBY_RELEASE_MONTH < 10
+#define MRUBY_RELEASE_MONTH_STR "0" MRB_STRINGIZE(MRUBY_RELEASE_MONTH)
+#else
+#define MRUBY_RELEASE_MONTH_STR MRB_STRINGIZE(MRUBY_RELEASE_MONTH)
+#endif
+#if MRUBY_RELEASE_DAY < 10
+#define MRUBY_RELEASE_DAY_STR "0" MRB_STRINGIZE(MRUBY_RELEASE_DAY)
+#else
+#define MRUBY_RELEASE_DAY_STR MRB_STRINGIZE(MRUBY_RELEASE_DAY)
+#endif
 
 /*
  * The year mruby was first created.
@@ -92,9 +106,9 @@ MRB_BEGIN_DECL
 /*
  * mruby's version, and release date.
  */
-#define MRUBY_DESCRIPTION      \
-  "mruby " MRUBY_VERSION       \
-  " (" MRUBY_RELEASE_DATE ") " \
+#define MRUBY_DESCRIPTION     \
+  "mruby " MRUBY_VERSION      \
+  " (" MRUBY_RELEASE_DATE ")" \
 
 /*
  * mruby's copyright information.
index 08e6f61..433f1bb 100644 (file)
@@ -1,3 +1,5 @@
+autoload :Pathname, 'pathname'
+
 class Object
   class << self
     def attr_block(*syms)
@@ -16,68 +18,10 @@ class String
   def relative_path
     relative_path_from(Dir.pwd)
   end
-
-  # Compatible with 1.9 on 1.8
-  unless (sprintf("%{a}", :a => 1) rescue false)
-    def %(params)
-      if params.is_a?(Hash)
-        str = self.clone
-        params.each do |k, v|
-          str.gsub!("%{#{k}}") { v }
-        end
-        str
-      else
-        if params.is_a?(Array)
-          sprintf(self, *params)
-        else
-          sprintf(self, params)
-        end
-      end
-    end
-  end
-end
-
-class Symbol
-  # Compatible with 1.9 on 1.8
-  unless method_defined?(:to_proc)
-    def to_proc
-      proc { |obj, *args| obj.send(self, *args) }
-    end
-  end
-end
-
-module Enumerable
-  # Compatible with 1.9 on 1.8
-  unless method_defined?(:each_with_object)
-    def each_with_object(memo)
-      return to_enum :each_with_object, memo unless block_given?
-      each { |obj| yield obj, memo }
-      memo
-    end
-  end
-end
-
-$pp_show = true
-
-if $verbose.nil?
-  if Rake.respond_to?(:verbose) && !Rake.verbose.nil?
-    if Rake.verbose.class == TrueClass
-      # verbose message logging
-      $pp_show = false
-    else
-      $pp_show = true
-      Rake.verbose(false)
-    end
-  else
-    # could not identify rake version
-    $pp_show = false
-  end
-else
-  $pp_show = false if $verbose
 end
 
 def _pp(cmd, src, tgt=nil, options={})
-  return unless $pp_show
+  return if Rake.verbose
 
   width = 5
   template = options[:indent] ? "%#{width*options[:indent]}s %s %s" : "%-#{width}s %s %s"
index 016b32b..9ba136c 100644 (file)
@@ -1,7 +1,11 @@
+require "mruby-core-ext"
 require "mruby/build/load_gems"
 require "mruby/build/command"
 
 module MRuby
+  autoload :Gem, "mruby/gem"
+  autoload :Lockfile, "mruby/lockfile"
+
   class << self
     def targets
       @targets ||= {}
@@ -22,7 +26,6 @@ module MRuby
 
     def initialize(name, &block)
       @name, @initializer = name.to_s, block
-      MRuby::Toolchain.toolchains ||= {}
       MRuby::Toolchain.toolchains[@name] = self
     end
 
@@ -30,13 +33,8 @@ module MRuby
       conf.instance_exec(conf, params, &@initializer)
     end
 
-    def self.load
-      Dir.glob("#{MRUBY_ROOT}/tasks/toolchains/*.rake").each do |file|
-        Kernel.load file
-      end
-    end
+    self.toolchains = {}
   end
-  Toolchain.load
 
   class Build
     class << self
@@ -45,7 +43,7 @@ module MRuby
     include Rake::DSL
     include LoadGems
     attr_accessor :name, :bins, :exts, :file_separator, :build_dir, :gem_clone_dir
-    attr_reader :libmruby_objs, :gems, :toolchains
+    attr_reader :libmruby_objs, :gems, :toolchains, :gem_dir_to_repo_url
     attr_writer :enable_bintest, :enable_test
 
     alias libmruby libmruby_objs
@@ -70,7 +68,7 @@ module MRuby
 
         @file_separator = '/'
         @build_dir = "#{build_dir}/#{@name}"
-        @gem_clone_dir = "#{build_dir}/mrbgems"
+        @gem_clone_dir = "#{build_dir}/repos/#{@name}"
         @cc = Command::Compiler.new(self, %w(.c))
         @cxx = Command::Compiler.new(self, %w(.cc .cxx .cpp))
         @objc = Command::Compiler.new(self, %w(.m))
@@ -90,7 +88,9 @@ module MRuby
         @cxx_abi_enabled = false
         @enable_bintest = false
         @enable_test = false
+        @enable_lock = true
         @toolchains = []
+        @gem_dir_to_repo_url = {}
 
         MRuby.targets[@name] = self
       end
@@ -118,6 +118,14 @@ module MRuby
       @enable_debug = true
     end
 
+    def disable_lock
+      @enable_lock = false
+    end
+
+    def lock_enabled?
+      Lockfile.enabled? && @enable_lock
+    end
+
     def disable_cxx_exception
       if @cxx_exception_enabled or @cxx_abi_enabled
         raise "cxx_exception already enabled"
@@ -155,8 +163,8 @@ module MRuby
       compilers.each { |c|
         c.defines += %w(MRB_ENABLE_CXX_EXCEPTION MRB_ENABLE_CXX_ABI)
         c.flags << c.cxx_compile_flag
+        c.flags = c.flags.flatten - c.cxx_invalid_flags.flatten
       }
-      compilers.each { |c| c.flags << c.cxx_compile_flag }
       linker.command = cxx.command if toolchains.find { |v| v == 'gcc' }
       @cxx_abi_enabled = true
     end
@@ -165,7 +173,7 @@ module MRuby
       obj = objfile(cxx_src) if obj.nil?
 
       file cxx_src => [src, __FILE__] do |t|
-        FileUtils.mkdir_p File.dirname t.name
+        mkdir_p File.dirname t.name
         IO.write t.name, <<EOS
 #define __STDC_CONSTANT_MACROS
 #define __STDC_LIMIT_MACROS
@@ -196,10 +204,15 @@ EOS
     end
 
     def toolchain(name, params={})
-      tc = Toolchain.toolchains[name.to_s]
-      fail "Unknown #{name} toolchain" unless tc
+      name = name.to_s
+      tc = Toolchain.toolchains[name] || begin
+        path = "#{MRUBY_ROOT}/tasks/toolchains/#{name}.rake"
+        fail "Unknown #{name} toolchain" unless File.exist?(path)
+        load path
+        Toolchain.toolchains[name]
+      end
       tc.setup(self, params)
-      @toolchains.unshift name.to_s
+      @toolchains.unshift name
     end
 
     def primary_toolchain
@@ -226,6 +239,10 @@ EOS
       gem :core => 'mruby-bin-mrbc'
     end
 
+    def locks
+      Lockfile.build(@name)
+    end
+
     def mrbcfile
       return @mrbcfile if @mrbcfile
 
@@ -255,15 +272,7 @@ EOS
       if name.is_a?(Array)
         name.flatten.map { |n| filename(n) }
       else
-        '"%s"' % name.gsub('/', file_separator)
-      end
-    end
-
-    def cygwin_filename(name)
-      if name.is_a?(Array)
-        name.flatten.map { |n| cygwin_filename(n) }
-      else
-        '"%s"' % `cygpath -w "#{filename(name)}"`.strip
+        name.gsub('/', file_separator)
       end
     end
 
@@ -303,7 +312,7 @@ EOS
     end
 
     def verbose_flag
-      $verbose ? ' -v' : ''
+      Rake.verbose ? ' -v' : ''
     end
 
     def run_test
@@ -327,7 +336,8 @@ EOS
       puts "         Binaries: #{@bins.join(', ')}" unless @bins.empty?
       unless @gems.empty?
         puts "    Included Gems:"
-        @gems.map do |gem|
+        gems = @gems.sort_by { |gem| gem.name }
+        gems.each do |gem|
           gem_version = " - #{gem.version}" if gem.version != '0.0.0'
           gem_summary = " - #{gem.summary}" if gem.summary
           puts "             #{gem.name}#{gem_version}#{gem_summary}"
@@ -369,7 +379,7 @@ EOS
     end
 
     def run_test
-      @test_runner.runner_options << ' -v' if $verbose
+      @test_runner.runner_options << verbose_flag
       mrbtest = exefile("#{build_dir}/bin/mrbtest")
       if (@test_runner.command == nil)
         puts "You should run #{mrbtest} on target device."
@@ -378,26 +388,5 @@ EOS
         @test_runner.run(mrbtest)
       end
     end
-
-    def big_endian
-      if @endian
-        puts "Endian has already specified as #{@endian}."
-        return
-      end
-      @endian = :big
-      @mrbc.compile_options += ' -E'
-      compilers.each do |c|
-        c.defines += %w(MRB_ENDIAN_BIG)
-      end
-    end
-
-    def little_endian
-      if @endian
-        puts "Endian has already specified as #{@endian}."
-        return
-      end
-      @endian = :little
-      @mrbc.compile_options += ' -e'
-    end
   end # CrossBuild
 end # MRuby
index 0f18e0e..bed0c3a 100644 (file)
@@ -4,7 +4,7 @@ module MRuby
   class Command
     include Rake::DSL
     extend Forwardable
-    def_delegators :@build, :filename, :objfile, :libfile, :exefile, :cygwin_filename
+    def_delegators :@build, :filename, :objfile, :libfile, :exefile
     attr_accessor :build, :command
 
     def initialize(build)
@@ -24,6 +24,14 @@ module MRuby
       target
     end
 
+    def shellquote(s)
+      if ENV['OS'] == 'Windows_NT'
+        "\"#{s}\""
+      else
+        "#{s}"
+      end
+    end
+
     NotFoundCommands = {}
 
     private
@@ -41,7 +49,7 @@ module MRuby
   class Command::Compiler < Command
     attr_accessor :flags, :include_paths, :defines, :source_exts
     attr_accessor :compile_options, :option_define, :option_include_path, :out_ext
-    attr_accessor :cxx_compile_flag, :cxx_exception_flag
+    attr_accessor :cxx_compile_flag, :cxx_exception_flag, :cxx_invalid_flags
 
     def initialize(build, source_exts=[])
       super(build)
@@ -50,9 +58,10 @@ module MRuby
       @source_exts = source_exts
       @include_paths = ["#{MRUBY_ROOT}/include"]
       @defines = %w()
-      @option_include_path = '-I%s'
-      @option_define = '-D%s'
-      @compile_options = '%{flags} -o %{outfile} -c %{infile}'
+      @option_include_path = %q[-I"%s"]
+      @option_define = %q[-D"%s"]
+      @compile_options = %q[%{flags} -o "%{outfile}" -c "%{infile}"]
+      @cxx_invalid_flags = []
     end
 
     alias header_search_paths include_paths
@@ -70,25 +79,16 @@ module MRuby
     def all_flags(_defines=[], _include_paths=[], _flags=[])
       define_flags = [defines, _defines].flatten.map{ |d| option_define % d }
       include_path_flags = [include_paths, _include_paths].flatten.map do |f|
-        if MRUBY_BUILD_HOST_IS_CYGWIN
-          option_include_path % cygwin_filename(f)
-        else
-          option_include_path % filename(f)
-        end
+        option_include_path % filename(f)
       end
       [flags, define_flags, include_path_flags, _flags].flatten.join(' ')
     end
 
     def run(outfile, infile, _defines=[], _include_paths=[], _flags=[])
-      FileUtils.mkdir_p File.dirname(outfile)
+      mkdir_p File.dirname(outfile)
       _pp "CC", infile.relative_path, outfile.relative_path
-      if MRUBY_BUILD_HOST_IS_CYGWIN
-        _run compile_options, { :flags => all_flags(_defines, _include_paths, _flags),
-                                :infile => cygwin_filename(infile), :outfile => cygwin_filename(outfile) }
-      else
-        _run compile_options, { :flags => all_flags(_defines, _include_paths, _flags),
-                                :infile => filename(infile), :outfile => filename(outfile) }
-      end
+      _run compile_options, { :flags => all_flags(_defines, _include_paths, _flags),
+                              :infile => filename(infile), :outfile => filename(outfile) }
     end
 
     def define_rules(build_dir, source_dir='')
@@ -127,13 +127,40 @@ module MRuby
     end
 
     private
+
+    #
+    # === Example of +.d+ file
+    #
+    # ==== Without <tt>-MP</tt> compiler flag
+    #
+    #   /build/host/src/array.o: \
+    #     /src/array.c \
+    #     /include/mruby/common.h \
+    #     /include/mruby/value.h \
+    #     /src/value_array.h
+    #
+    # ==== With <tt>-MP</tt> compiler flag
+    #
+    #   /build/host/src/array.o: \
+    #     /src/array.c \
+    #     /include/mruby/common.h \
+    #     /include/mruby/value.h \
+    #     /src/value_array.h
+    #
+    #   /include/mruby/common.h:
+    #
+    #   /include/mruby/value.h:
+    #
+    #   /src/value_array.h:
+    #
     def get_dependencies(file)
       file = file.ext('d') unless File.extname(file) == '.d'
+      deps = []
       if File.exist?(file)
-        File.read(file).gsub("\\\n ", "").scan(/^\S+:\s+(.+)$/).flatten.map {|s| s.split(' ') }.flatten
-      else
-        []
-      end + [ MRUBY_CONFIG ]
+        File.foreach(file){|line| deps << $1 if /^ +(.*?)(?: *\\)?$/ =~ line}
+        deps.uniq!
+      end
+      deps << MRUBY_CONFIG
     end
   end
 
@@ -148,18 +175,14 @@ module MRuby
       @flags_before_libraries, @flags_after_libraries = [], []
       @libraries = []
       @library_paths = []
-      @option_library = '-l%s'
-      @option_library_path = '-L%s'
-      @link_options = "%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}"
+      @option_library = %q[-l"%s"]
+      @option_library_path = %q[-L"%s"]
+      @link_options = %Q[%{flags} -o "%{outfile}" %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}]
     end
 
     def all_flags(_library_paths=[], _flags=[])
       library_path_flags = [library_paths, _library_paths].flatten.map do |f|
-        if MRUBY_BUILD_HOST_IS_CYGWIN
-          option_library_path % cygwin_filename(f)
-        else
-          option_library_path % filename(f)
-        end
+        option_library_path % filename(f)
       end
       [flags, library_path_flags, _flags].flatten.join(' ')
     end
@@ -169,23 +192,15 @@ module MRuby
     end
 
     def run(outfile, objfiles, _libraries=[], _library_paths=[], _flags=[], _flags_before_libraries=[], _flags_after_libraries=[])
-      FileUtils.mkdir_p File.dirname(outfile)
+      mkdir_p File.dirname(outfile)
       library_flags = [libraries, _libraries].flatten.map { |d| option_library % d }
 
       _pp "LD", outfile.relative_path
-      if MRUBY_BUILD_HOST_IS_CYGWIN
-        _run link_options, { :flags => all_flags(_library_paths, _flags),
-                             :outfile => cygwin_filename(outfile) , :objs => cygwin_filename(objfiles).join(' '),
-                             :flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '),
-                             :flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '),
-                             :libs => library_flags.join(' ') }
-      else
-        _run link_options, { :flags => all_flags(_library_paths, _flags),
-                             :outfile => filename(outfile) , :objs => filename(objfiles).join(' '),
-                             :flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '),
-                             :flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '),
-                             :libs => library_flags.join(' ') }
-      end
+      _run link_options, { :flags => all_flags(_library_paths, _flags),
+                            :outfile => filename(outfile) , :objs => filename(objfiles).map{|f| %Q["#{f}"]}.join(' '),
+                            :flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '),
+                            :flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '),
+                            :libs => library_flags.join(' ') }
     end
   end
 
@@ -195,17 +210,13 @@ module MRuby
     def initialize(build)
       super
       @command = ENV['AR'] || 'ar'
-      @archive_options = 'rs %{outfile} %{objs}'
+      @archive_options = 'rs "%{outfile}" %{objs}'
     end
 
     def run(outfile, objfiles)
-      FileUtils.mkdir_p File.dirname(outfile)
+      mkdir_p File.dirname(outfile)
       _pp "AR", outfile.relative_path
-      if MRUBY_BUILD_HOST_IS_CYGWIN
-        _run archive_options, { :outfile => cygwin_filename(outfile), :objs => cygwin_filename(objfiles).join(' ') }
-      else
-        _run archive_options, { :outfile => filename(outfile), :objs => filename(objfiles).join(' ') }
-      end
+      _run archive_options, { :outfile => filename(outfile), :objs => filename(objfiles).map{|f| %Q["#{f}"]}.join(' ') }
     end
   end
 
@@ -215,11 +226,11 @@ module MRuby
     def initialize(build)
       super
       @command = 'bison'
-      @compile_options = '-o %{outfile} %{infile}'
+      @compile_options = %q[-o "%{outfile}" "%{infile}"]
     end
 
     def run(outfile, infile)
-      FileUtils.mkdir_p File.dirname(outfile)
+      mkdir_p File.dirname(outfile)
       _pp "YACC", infile.relative_path, outfile.relative_path
       _run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) }
     end
@@ -231,11 +242,11 @@ module MRuby
     def initialize(build)
       super
       @command = 'gperf'
-      @compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
+      @compile_options = %q[-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" "%{infile}" > "%{outfile}"]
     end
 
     def run(outfile, infile)
-      FileUtils.mkdir_p File.dirname(outfile)
+      mkdir_p File.dirname(outfile)
       _pp "GPERF", infile.relative_path, outfile.relative_path
       _run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) }
     end
@@ -243,36 +254,50 @@ module MRuby
 
   class Command::Git < Command
     attr_accessor :flags
-    attr_accessor :clone_options, :pull_options, :checkout_options
+    attr_accessor :clone_options, :pull_options, :checkout_options, :checkout_detach_options, :reset_options
 
     def initialize(build)
       super
       @command = 'git'
       @flags = %w[]
       @clone_options = "clone %{flags} %{url} %{dir}"
-      @pull_options = "pull"
-      @checkout_options = "checkout %{checksum_hash}"
+      @pull_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} pull"
+      @checkout_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} checkout %{checksum_hash}"
+      @checkout_detach_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} checkout --detach %{checksum_hash}"
+      @reset_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} reset %{checksum_hash}"
     end
 
     def run_clone(dir, url, _flags = [])
       _pp "GIT", url, dir.relative_path
-      _run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => url, :dir => filename(dir) }
+      _run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => shellquote(url), :dir => shellquote(filename(dir)) }
     end
 
     def run_pull(dir, url)
-      root = Dir.pwd
-      Dir.chdir dir
       _pp "GIT PULL", url, dir.relative_path
-      _run pull_options
-      Dir.chdir root
+      _run pull_options, { :repo_dir => shellquote(dir) }
     end
 
     def run_checkout(dir, checksum_hash)
-      root = Dir.pwd
-      Dir.chdir dir
-      _pp "GIT CHECKOUT", checksum_hash
-      _run checkout_options, { :checksum_hash => checksum_hash }
-      Dir.chdir root
+      _pp "GIT CHECKOUT", dir, checksum_hash
+      _run checkout_options, { :checksum_hash => checksum_hash, :repo_dir => shellquote(dir) }
+    end
+
+    def run_checkout_detach(dir, checksum_hash)
+      _pp "GIT CHECKOUT DETACH", dir, checksum_hash
+      _run checkout_detach_options, { :checksum_hash => checksum_hash, :repo_dir => shellquote(dir) }
+    end
+
+    def run_reset_hard(dir, checksum_hash)
+      _pp "GIT RESET", dir, checksum_hash
+      _run reset_options, { :checksum_hash => checksum_hash, :repo_dir => shellquote(dir) }
+    end
+
+    def commit_hash(dir)
+      `#{@command} --git-dir #{shellquote(dir +'/.git')} --work-tree #{shellquote(dir)} rev-parse --verify HEAD`.strip
+    end
+
+    def current_branch(dir)
+      `#{@command} --git-dir #{shellquote(dir + '/.git')} --work-tree #{shellquote(dir)} rev-parse --abbrev-ref HEAD`.strip
     end
   end
 
@@ -291,7 +316,9 @@ module MRuby
       infiles.each do |f|
         _pp "MRBC", f.relative_path, nil, :indent => 2
       end
-      IO.popen("#{filename @command} #{@compile_options % {:funcname => funcname}} #{filename(infiles).join(' ')}", 'r+') do |io|
+      cmd = %Q["#{filename @command}" #{@compile_options % {:funcname => funcname}} #{filename(infiles).map{|f| %Q["#{f}"]}.join(' ')}]
+      puts cmd if Rake.verbose
+      IO.popen(cmd, 'r+') do |io|
         out.puts io.read
       end
       # if mrbc execution fail, drop the file
index 723be6f..522b8a1 100644 (file)
@@ -13,13 +13,12 @@ module MRuby
     end
 
     def gem(gemdir, &block)
-      caller_dir = File.expand_path(File.dirname(/^(.*?):\d/.match(caller.first).to_a[1]))
-
       if gemdir.is_a?(Hash)
         gemdir = load_special_path_gem(gemdir)
       elsif GemBox.path && gemdir.is_a?(String)
         gemdir = File.expand_path(gemdir, File.dirname(GemBox.path))
       else
+        caller_dir = File.expand_path(File.dirname(caller(1,1)[0][/^(.*?):\d/,1]))
         gemdir = File.expand_path(gemdir, caller_dir)
       end
 
@@ -58,7 +57,7 @@ module MRuby
         if File.exist? mgem_list_dir
           git.run_pull mgem_list_dir, mgem_list_url if $pull_gems
         else
-          FileUtils.mkdir_p mgem_list_dir
+          mkdir_p mgem_list_dir
           git.run_clone mgem_list_dir, mgem_list_url, "--depth 1"
         end
 
@@ -83,27 +82,41 @@ module MRuby
         # by default the 'master' branch is used
         branch = params[:branch] ? params[:branch] : 'master'
 
+        lock = locks[url] if lock_enabled?
+
         if File.exist?(gemdir)
           if $pull_gems
+            # Jump to the top of the branch
+            git.run_checkout gemdir, branch
             git.run_pull gemdir, url
-          else
-            gemdir
+          elsif params[:checksum_hash]
+            git.run_checkout_detach gemdir, params[:checksum_hash]
+          elsif lock
+            git.run_checkout_detach gemdir, lock['commit']
           end
         else
           options = [params[:options]] || []
           options << "--recursive"
           options << "--branch \"#{branch}\""
           options << "--depth 1" unless params[:checksum_hash]
-          FileUtils.mkdir_p "#{gem_clone_dir}"
+          mkdir_p "#{gem_clone_dir}"
           git.run_clone gemdir, url, options
-        end
 
-        if params[:checksum_hash]
           # Jump to the specified commit
-          git.run_checkout gemdir, params[:checksum_hash]
-        else
-          # Jump to the top of the branch
-          git.run_checkout gemdir, branch if $pull_gems
+          if params[:checksum_hash]
+            git.run_checkout_detach gemdir, params[:checksum_hash]
+          elsif lock
+            git.run_checkout_detach gemdir, lock['commit']
+          end
+        end
+
+        if lock_enabled?
+          @gem_dir_to_repo_url[gemdir] = url unless params[:path]
+          locks[url] = {
+            'url' => url,
+            'branch' => git.current_branch(gemdir),
+            'commit' => git.commit_hash(gemdir),
+          }
         end
 
         gemdir << "/#{params[:path]}" if params[:path]
index ce2e01a..4c3cd7f 100644 (file)
@@ -1,7 +1,6 @@
-require 'pathname'
 require 'forwardable'
-require 'tsort'
-require 'shellwords'
+autoload :TSort, 'tsort'
+autoload :Shellwords, 'shellwords'
 
 module MRuby
   module Gem
@@ -92,6 +91,9 @@ module MRuby
         build.libmruby_objs << @objs
 
         instance_eval(&@build_config_initializer) if @build_config_initializer
+
+        repo_url = build.gem_dir_to_repo_url[dir]
+        build.locks[repo_url]['version'] = version if repo_url
       end
 
       def setup_compilers
@@ -104,6 +106,15 @@ module MRuby
         define_gem_init_builder if @generate_functions
       end
 
+      def for_windows?
+        if build.kind_of?(MRuby::CrossBuild)
+          return %w(x86_64-w64-mingw32 i686-w64-mingw32).include?(build.host_target)
+        elsif build.kind_of?(MRuby::Build)
+          return ('A'..'Z').to_a.any? { |vol| Dir.exist?("#{vol}:") }
+        end
+        return false
+      end
+
       def add_dependency(name, *requirements)
         default_gem = requirements.last.kind_of?(Hash) ? requirements.pop : nil
         requirements = ['>= 0.0.0'] if requirements.empty?
@@ -155,7 +166,7 @@ module MRuby
       def define_gem_init_builder
         file objfile("#{build_dir}/gem_init") => [ "#{build_dir}/gem_init.c", File.join(dir, "mrbgem.rake") ]
         file "#{build_dir}/gem_init.c" => [build.mrbcfile, __FILE__] + [rbfiles].flatten do |t|
-          FileUtils.mkdir_p build_dir
+          mkdir_p build_dir
           generate_gem_init("#{build_dir}/gem_init.c")
         end
       end
@@ -267,16 +278,18 @@ module MRuby
       # ~> compare algorithm
       #
       # Example:
+      #    ~> 2     means >= 2.0.0 and < 3.0.0
       #    ~> 2.2   means >= 2.2.0 and < 3.0.0
-      #    ~> 2.2.0 means >= 2.2.0 and < 2.3.0
+      #    ~> 2.2.2 means >= 2.2.2 and < 2.3.0
       def twiddle_wakka_ok?(other)
         gr_or_eql = (self <=> other) >= 0
-        still_minor = (self <=> other.skip_minor) < 0
-        gr_or_eql and still_minor
+        still_major_or_minor = (self <=> other.skip_major_or_minor) < 0
+        gr_or_eql and still_major_or_minor
       end
 
-      def skip_minor
+      def skip_major_or_minor
         a = @ary.dup
+        a << 0 if a.size == 1 # ~> 2 can also be represented as ~> 2.0
         a.slice!(-1)
         a[-1] = a[-1].succ
         a
diff --git a/third-party/mruby/lib/mruby/lockfile.rb b/third-party/mruby/lib/mruby/lockfile.rb
new file mode 100644 (file)
index 0000000..0d2455b
--- /dev/null
@@ -0,0 +1,81 @@
+autoload :YAML, 'yaml'
+
+module MRuby
+  autoload :Source, 'mruby/source'
+
+  class Lockfile
+    class << self
+      def enable
+        @enabled = true
+      end
+
+      def disable
+        @enabled = false
+      end
+
+      def enabled?
+        @enabled
+      end
+
+      def build(target_name)
+        instance.build(target_name)
+      end
+
+      def write
+        instance.write if enabled?
+      end
+
+      def instance
+        @instance ||= new("#{MRUBY_CONFIG}.lock")
+      end
+    end
+
+    def initialize(filename)
+      @filename = filename
+    end
+
+    def build(target_name)
+      read[target_name] ||= {}
+    end
+
+    def write
+      locks = {"mruby_version" => mruby}
+      locks["builds"] = @builds if @builds
+      File.write(@filename, YAML.dump(locks))
+    end
+
+    private
+
+    def read
+      @builds ||= if File.exist?(@filename)
+                    YAML.load_file(@filename)["builds"] || {}
+                  else
+                    {}
+                  end
+    end
+
+    def shellquote(s)
+      if ENV['OS'] == 'Windows_NT'
+        "\"#{s}\""
+      else
+        "'#{s}'"
+      end
+    end
+
+    def mruby
+      mruby = {
+        'version' => MRuby::Source::MRUBY_VERSION,
+        'release_no' => MRuby::Source::MRUBY_RELEASE_NO,
+      }
+
+      git_dir = "#{MRUBY_ROOT}/.git"
+      if File.directory?(git_dir)
+        mruby['git_commit'] = `git --git-dir #{shellquote(git_dir)} --work-tree #{shellquote(MRUBY_ROOT)} rev-parse --verify HEAD`.strip
+      end
+
+      mruby
+    end
+
+    enable
+  end
+end
index 5819a32..a305c7b 100644 (file)
@@ -6,7 +6,9 @@ module MRuby
     ROOT = Pathname.new(File.expand_path('../../../',__FILE__))
 
     # Reads a constant defined at version.h
-    MRUBY_READ_VERSION_CONSTANT = Proc.new { |name| ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?$/)[1] }
+    MRUBY_READ_VERSION_CONSTANT = Proc.new do |name|
+      ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?\r?$/)[1]
+    end
 
     MRUBY_RUBY_VERSION = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_VERSION']
     MRUBY_RUBY_ENGINE = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_ENGINE']
index cd2d858..3a9d2f8 100755 (executable)
@@ -1,605 +1,2 @@
-#!/usr/bin/env ruby
-
-# Original is https://github.com/jimweirich/rake/
-# Copyright (c) 2003 Jim Weirich
-# License: MIT-LICENSE
-
-require 'getoptlong'
-require 'fileutils'
-
-$rake_fiber_table = {}
-$rake_jobs = 1
-$rake_failed = []
-
-class String
-  def ext(newext='')
-    return self.dup if ['.', '..'].include? self
-    if newext != ''
-      newext = (newext =~ /^\./) ? newext : ("." + newext)
-    end
-    self.chomp(File.extname(self)) << newext
-  end
-
-  def pathmap(spec=nil, &block)
-    return self if spec.nil?
-    result = ''
-    spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag|
-      case frag
-      when '%f'
-        result << File.basename(self)
-      when '%n'
-        result << File.basename(self).ext
-      when '%d'
-        result << File.dirname(self)
-      when '%x'
-        result << File.extname(self)
-      when '%X'
-        result << self.ext
-      when '%p'
-        result << self
-      when '%s'
-        result << (File::ALT_SEPARATOR || File::SEPARATOR)
-      when '%-'
-        # do nothing
-      when '%%'
-        result << "%"
-      when /%(-?\d+)d/
-        result << pathmap_partial($1.to_i)
-      when /^%\{([^}]*)\}(\d*[dpfnxX])/
-        patterns, operator = $1, $2
-        result << pathmap('%' + operator).pathmap_replace(patterns, &block)
-      when /^%/
-        fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'"
-      else
-        result << frag
-      end
-    end
-    result
-  end
-end
-
-module MiniRake
-  class Task
-    TASKS = Hash.new
-    RULES = Array.new
-
-    # List of prerequisites for a task.
-    attr_reader :prerequisites
-
-    # Source dependency for rule synthesized tasks.  Nil if task was not
-    # sythesized from a rule.
-    attr_accessor :source
-
-    # Create a task named +task_name+ with no actions or prerequisites..
-    # use +enhance+ to add actions and prerequisites.
-    def initialize(task_name)
-      @name = task_name
-      @prerequisites = []
-      @actions = []
-    end
-
-    # Enhance a task with prerequisites or actions.  Returns self.
-    def enhance(deps=nil, &block)
-      @prerequisites |= deps if deps
-      @actions << block if block_given?
-      self
-    end
-
-    # Name of the task.
-    def name
-      @name.to_s
-    end
-
-    def done?; @done end
-    def running?; @running end
-
-    # Invoke the task if it is needed. Prerequisites are invoked first.
-    def invoke
-      puts "Invoke #{name} (already=[#{@already_invoked}], needed=[#{needed?}])" if $trace
-      return if @already_invoked
-      prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
-      prerequisites.each do |n|
-        t = Task[n]
-        unless t.done?
-          return prerequisites.select{|v| v = Task[v]; v && (!v.done? || !v.running?) }
-        end
-      end
-
-      @already_invoked = true
-
-      if needed?
-        @running = true
-        if $rake_root_fiber
-          return Fiber.new do
-            self.execute
-            $rake_root_fiber.transfer
-          end
-        else
-          self.execute
-        end
-      end
-
-      @done = true
-    end
-
-    # Execute the actions associated with this task.
-    def execute
-      puts "Execute #{name}" if $trace
-      self.class.enhance_with_matching_rule(name) if @actions.empty?
-      unless $dryrun
-        @actions.each { |act| act.call(self) }
-      end
-      @done = true
-      @running = false
-    end
-
-    # Is this task needed?
-    def needed?
-      true
-    end
-
-    # Timestamp for this task.  Basic tasks return the current time for
-    # their time stamp.  Other tasks can be more sophisticated.
-    def timestamp
-      Time.now
-    end
-
-    # Class Methods ----------------------------------------------------
-
-    class << self
-
-      # Clear the task list.  This cause rake to immediately forget all
-      # the tasks that have been assigned.  (Normally used in the unit
-      # tests.)
-      def clear
-        TASKS.clear
-        RULES.clear
-      end
-
-      # List of all defined tasks.
-      def tasks
-        TASKS.keys.sort.collect { |tn| Task[tn] }
-      end
-
-      # Return a task with the given name.  If the task is not currently
-      # known, try to synthesize one from the defined rules.  If no
-      # rules are found, but an existing file matches the task name,
-      # assume it is a file task with no dependencies or actions.
-      def [](task_name)
-        task_name = task_name.to_s
-        if task = TASKS[task_name]
-          return task
-        end
-        if task = enhance_with_matching_rule(task_name)
-          return task
-        end
-        if File.exist?(task_name)
-          return FileTask.define_task(task_name)
-        end
-        fail "Don't know how to rake #{task_name}"
-      end
-
-      # Define a task given +args+ and an option block.  If a rule with
-      # the given name already exists, the prerequisites and actions are
-      # added to the existing task.
-      def define_task(args, &block)
-        task_name, deps = resolve_args(args)
-        lookup(task_name).enhance([deps].flatten, &block)
-      end
-
-      # Define a rule for synthesizing tasks.
-      def create_rule(args, &block)
-        pattern, deps = resolve_args(args)
-        pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
-        RULES << [pattern, deps, block]
-      end
-
-
-      # Lookup a task.  Return an existing task if found, otherwise
-      # create a task of the current type.
-      def lookup(task_name)
-        name = task_name.to_s
-        TASKS[name] ||= self.new(name)
-      end
-
-      # If a rule can be found that matches the task name, enhance the
-      # task with the prerequisites and actions from the rule.  Set the
-      # source attribute of the task appropriately for the rule.  Return
-      # the enhanced task or nil of no rule was found.
-      def enhance_with_matching_rule(task_name)
-        RULES.each do |pattern, extensions, block|
-          if pattern.match(task_name)
-            ext = extensions.first
-            deps = extensions[1..-1]
-            case ext
-            when String
-              source = task_name.sub(/\.[^.]*$/, ext)
-            when Proc
-              source = ext.call(task_name)
-            else
-              fail "Don't know how to handle rule dependent: #{ext.inspect}"
-            end
-            if File.exist?(source)
-              task = FileTask.define_task({task_name => [source]+deps}, &block)
-              task.source = source
-              return task
-            end
-          end
-        end
-        nil
-      end
-
-      private
-
-      # Resolve the arguments for a task/rule.
-      def resolve_args(args)
-        case args
-        when Hash
-          fail "Too Many Task Names: #{args.keys.join(' ')}" if args.size > 1
-          fail "No Task Name Given" if args.size < 1
-          task_name = args.keys[0]
-          deps = args[task_name]
-          deps = [deps] if (String===deps) || (Regexp===deps) || (Proc===deps)
-        else
-          task_name = args
-          deps = []
-        end
-        [task_name, deps]
-      end
-    end
-  end
-
-
-  ######################################################################
-  class FileTask < Task
-    # Is this file task needed?  Yes if it doesn't exist, or if its time
-    # stamp is out of date.
-    def needed?
-      return true unless File.exist?(name)
-      prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
-      latest_prereq = prerequisites.collect{|n| Task[n].timestamp}.max
-      return false if latest_prereq.nil?
-      timestamp < latest_prereq
-    end
-
-    # Time stamp for file task.
-    def timestamp
-      return Time.at(0) unless File.exist?(name)
-      stat = File::stat(name.to_s)
-      stat.directory? ? Time.at(0) : stat.mtime
-    end
-  end
-
-  module DSL
-    # Declare a basic task.
-    def task(args, &block)
-      MiniRake::Task.define_task(args, &block)
-    end
-
-    # Declare a file task.
-    def file(args, &block)
-      MiniRake::FileTask.define_task(args, &block)
-    end
-
-    # Declare a set of files tasks to create the given directories on
-    # demand.
-    def directory(args, &block)
-      MiniRake::FileTask.define_task(args) do |t|
-        block.call(t) unless block.nil?
-        dir = args.is_a?(Hash) ? args.keys.first : args
-        (dir.split(File::SEPARATOR) + ['']).inject do |acc, part|
-          (acc + File::SEPARATOR).tap do |d|
-            Dir.mkdir(d) unless File.exists? d
-          end + part
-        end
-      end
-    end
-
-    # Declare a rule for auto-tasks.
-    def rule(args, &block)
-      MiniRake::Task.create_rule(args, &block)
-    end
-
-    # Write a message to standard out if $verbose is enabled.
-    def log(msg)
-      print "  " if $trace && $verbose
-      puts msg if $verbose
-    end
-
-    # Run the system command +cmd+.
-    def sh(cmd)
-      puts cmd if $verbose
-
-      if !$rake_root_fiber || Fiber.current == $rake_root_fiber
-        system(cmd) or fail "Command Failed: [#{cmd}]"
-        return
-      end
-
-      pid = Process.spawn(cmd)
-      $rake_fiber_table[pid] = {
-        fiber: Fiber.current,
-        command: cmd,
-        process_waiter: Process.detach(pid)
-      }
-      $rake_root_fiber.transfer
-    end
-
-    def desc(text)
-    end
-  end
-end
-
-Rake = MiniRake
-extend MiniRake::DSL
-
-
-######################################################################
-# Task Definition Functions ...
-
-######################################################################
-# Rake main application object.  When invoking +rake+ from the command
-# line, a RakeApp object is created and run.
-#
-class RakeApp
-  RAKEFILES = ['rakefile', 'Rakefile']
-
-  OPTIONS = [
-    ['--dry-run',  '-n', GetoptLong::NO_ARGUMENT,
-      "Do a dry run without executing actions."],
-    ['--help',     '-H', GetoptLong::NO_ARGUMENT,
-      "Display this help message."],
-    ['--libdir',   '-I', GetoptLong::REQUIRED_ARGUMENT,
-      "Include LIBDIR in the search path for required modules."],
-    ['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
-      "Do not search parent directories for the Rakefile."],
-    ['--quiet',    '-q', GetoptLong::NO_ARGUMENT,
-      "Do not log messages to standard output (default)."],
-    ['--rakefile', '-f', GetoptLong::REQUIRED_ARGUMENT,
-      "Use FILE as the rakefile."],
-    ['--require',  '-r', GetoptLong::REQUIRED_ARGUMENT,
-      "Require MODULE before executing rakefile."],
-    ['--tasks',    '-T', GetoptLong::NO_ARGUMENT,
-      "Display the tasks and dependencies, then exit."],
-    ['--pull-gems','-p', GetoptLong::NO_ARGUMENT,
-      "Pull all git mrbgems."],
-    ['--trace',    '-t', GetoptLong::NO_ARGUMENT,
-      "Turn on invoke/execute tracing."],
-    ['--usage',    '-h', GetoptLong::NO_ARGUMENT,
-      "Display usage."],
-    ['--verbose',  '-v', GetoptLong::NO_ARGUMENT,
-      "Log message to standard output."],
-    ['--directory', '-C', GetoptLong::REQUIRED_ARGUMENT,
-      "Change executing directory of rakefiles."],
-    ['--jobs', '-j', GetoptLong::REQUIRED_ARGUMENT,
-      'Execute rake with parallel jobs.']
-  ]
-
-  # Create a RakeApp object.
-  def initialize
-    @rakefile = nil
-    @nosearch = false
-  end
-
-  # True if one of the files in RAKEFILES is in the current directory.
-  # If a match is found, it is copied into @rakefile.
-  def have_rakefile
-    RAKEFILES.each do |fn|
-      if File.exist?(fn)
-        @rakefile = fn
-        return true
-      end
-    end
-    return false
-  end
-
-  # Display the program usage line.
-  def usage
-      puts "rake [-f rakefile] {options} targets..."
-  end
-
-  # Display the rake command line help.
-  def help
-    usage
-    puts
-    puts "Options are ..."
-    puts
-    OPTIONS.sort.each do |long, short, mode, desc|
-      if mode == GetoptLong::REQUIRED_ARGUMENT
-        if desc =~ /\b([A-Z]{2,})\b/
-          long = long + "=#{$1}"
-        end
-      end
-      printf "  %-20s (%s)\n", long, short
-      printf "      %s\n", desc
-    end
-  end
-
-  # Display the tasks and dependencies.
-  def display_tasks
-    MiniRake::Task.tasks.each do |t|
-      puts "#{t.class} #{t.name}"
-      t.prerequisites.each { |pre| puts "    #{pre}" }
-    end
-  end
-
-  # Return a list of the command line options supported by the
-  # program.
-  def command_line_options
-    OPTIONS.collect { |lst| lst[0..-2] }
-  end
-
-  # Do the option defined by +opt+ and +value+.
-  def do_option(opt, value)
-    case opt
-    when '--dry-run'
-      $dryrun = true
-      $trace = true
-    when '--help'
-      help
-      exit
-    when '--libdir'
-      $:.push(value)
-    when '--nosearch'
-      @nosearch = true
-    when '--quiet'
-      $verbose = false
-    when '--rakefile'
-      RAKEFILES.clear
-      RAKEFILES << value
-    when '--require'
-      require value
-    when '--tasks'
-      $show_tasks = true
-    when '--pull-gems'
-      $pull_gems = true
-    when '--trace'
-      $trace = true
-    when '--usage'
-      usage
-      exit
-    when '--verbose'
-      $verbose = true
-    when '--version'
-      puts "rake, version #{RAKEVERSION}"
-      exit
-    when '--directory'
-      Dir.chdir value
-    when '--jobs'
-      $rake_jobs = [value.to_i, 1].max
-    else
-      fail "Unknown option: #{opt}"
-    end
-  end
-
-  # Read and handle the command line options.
-  def handle_options
-    $verbose = false
-    $pull_gems = false
-    opts = GetoptLong.new(*command_line_options)
-    opts.each { |opt, value| do_option(opt, value) }
-  end
-
-  # Run the +rake+ application.
-  def run
-    handle_options
-
-    unless $rake_root_fiber
-      require 'fiber'
-      $rake_root_fiber = Fiber.current
-    end
-
-    begin
-      here = Dir.pwd
-      while ! have_rakefile
-        Dir.chdir("..")
-        if Dir.pwd == here || @nosearch
-          fail "No Rakefile found (looking for: #{RAKEFILES.join(', ')})"
-        end
-        here = Dir.pwd
-      end
-      root_tasks = []
-      ARGV.each do |task_name|
-        if /^(\w+)=(.*)/.match(task_name)
-          ENV[$1] = $2
-        else
-          root_tasks << task_name
-        end
-      end
-      puts "(in #{Dir.pwd})"
-      $rakefile = @rakefile
-      load @rakefile
-      if $show_tasks
-        display_tasks
-      else
-        root_tasks.push("default") if root_tasks.empty?
-        # revese tasks for popping
-        root_tasks.reverse!
-
-        tasks = []
-        until root_tasks.empty?
-          root_name = root_tasks.pop
-          tasks << root_name
-          until tasks.empty?
-            task_name = tasks.pop
-            t = MiniRake::Task[task_name]
-            f = t.invoke
-
-            # append additional tasks to task queue
-            if f.kind_of?(Array)
-              tasks.push(*f)
-              tasks.uniq!
-            end
-
-            unless f.kind_of? Fiber
-              tasks.insert 0, task_name unless t.done?
-              if root_name == task_name
-                wait_process
-              end
-              next
-            end
-
-            wait_process while $rake_fiber_table.size >= $rake_jobs
-
-            f.transfer
-          end
-        end
-
-        wait_process until $rake_fiber_table.empty?
-      end
-    rescue Exception => e
-      begin
-        $rake_failed << e
-        wait_process until $rake_fiber_table.empty?
-      rescue Exception => next_e
-        e = next_e
-        retry
-      end
-    end
-
-    return if $rake_failed.empty?
-
-    puts "rake aborted!"
-    $rake_failed.each do |ex|
-      puts ex.message
-      if $trace || $verbose
-        puts ex.backtrace.join("\n")
-      else
-        puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
-      end
-    end
-    exit 1
-  end
-
-  def wait_process(count = 0)
-    dur = [0.0001 * (10 ** count), 1].min
-    sleep dur
-
-    exited = []
-    $rake_fiber_table.each do |pid, v|
-      exited << pid unless v[:process_waiter].alive?
-    end
-
-    exited.each do |pid|
-      ent = $rake_fiber_table.delete pid
-      st = ent[:process_waiter].value
-
-      # ignore process that isn't created by `sh` method
-      return if ent.nil?
-
-      if st.exitstatus != 0
-        raise "Command Failed: [#{ent[:command]}]"
-      end
-
-      fail 'task scheduling bug!' if $rake_fiber_table.size >= $rake_jobs
-
-      ent[:fiber].transfer
-    end
-
-    wait_process(count + 1) if !$rake_fiber_table.empty? && exited.empty?
-  end
-
-end
-
-if __FILE__ == $0 then
-  RakeApp.new.run
-end
+#! /usr/bin/env ruby
+exec "rake", *ARGV
index 23e65fc..de1e9a5 100644 (file)
@@ -71,6 +71,10 @@ MRuby::GemBox.new do |conf|
   # Use toplevel object (main) methods extension
   conf.gem :core => "mruby-toplevel-ext"
 
+  # Use Rational/Complex numbers
+  conf.gem :core => "mruby-rational"
+  conf.gem :core => "mruby-complex"
+
   # Generate mirb command
   conf.gem :core => "mruby-bin-mirb"
 
@@ -86,6 +90,12 @@ MRuby::GemBox.new do |conf|
   # Use class/module extension
   conf.gem :core => "mruby-class-ext"
 
+  # Use Method/UnboundMethod class
+  conf.gem :core => "mruby-method"
+
+  # Use eval()
+  conf.gem :core => "mruby-eval"
+
   # Use mruby-compiler to build other mrbgems
   conf.gem :core => "mruby-compiler"
 end
index 58d4428..882caf1 100644 (file)
@@ -2,5 +2,4 @@ MRuby::Gem::Specification.new('mruby-array-ext') do |spec|
   spec.license = 'MIT'
   spec.author  = 'mruby developers'
   spec.summary = 'Array class extension'
-  spec.add_test_dependency 'mruby-enumerator', core: 'mruby-enumerator'
 end
index 387bd6c..f3246af 100644 (file)
@@ -90,6 +90,22 @@ class Array
 
   ##
   # call-seq:
+  #    ary.difference(other_ary1, other_ary2, ...)   -> new_ary
+  #
+  # Returns a new array that is a copy of the original array, removing all
+  # occurrences of any item that also appear in +other_ary+. The order is
+  # preserved from the original array.
+  #
+  def difference(*args)
+    ary = self
+    args.each do |x|
+      ary = ary - x
+    end
+    ary
+  end
+
+  ##
+  # call-seq:
   #    ary | other_ary     -> new_ary
   #
   # Set Union---Returns a new array by joining this array with
@@ -159,6 +175,24 @@ class Array
 
   ##
   # call-seq:
+  #    ary.intersection(other_ary,...)  -> new_ary
+  #
+  # Set Intersection---Returns a new array containing elements common to
+  # this array and <i>other_ary</i>s, removing duplicates. The order is
+  # preserved from the original array.
+  #
+  #    [1, 2, 3].intersection([3, 4, 1], [1, 3, 5])  #=> [1, 3]
+  #
+  def intersection(*args)
+    ary = self
+    args.each do |x|
+      ary = ary & x
+    end
+    ary
+  end
+
+  ##
+  # call-seq:
   #    ary.flatten -> new_ary
   #    ary.flatten(level) -> new_ary
   #
@@ -654,37 +688,6 @@ class Array
 
   ##
   #  call-seq:
-  #     ary.delete_if { |item| block }  -> ary
-  #     ary.delete_if                   -> Enumerator
-  #
-  #  Deletes every element of +self+ for which block evaluates to +true+.
-  #
-  #  The array is changed instantly every time the block is called, not after
-  #  the iteration is over.
-  #
-  #  See also Array#reject!
-  #
-  #  If no block is given, an Enumerator is returned instead.
-  #
-  #     scores = [ 97, 42, 75 ]
-  #     scores.delete_if {|score| score < 80 }   #=> [97]
-
-  def delete_if(&block)
-    return to_enum :delete_if unless block
-
-    idx = 0
-    while idx < self.size do
-      if block.call(self[idx])
-        self.delete_at(idx)
-      else
-        idx += 1
-      end
-    end
-    self
-  end
-
-  ##
-  #  call-seq:
   #     ary.keep_if { |item| block } -> ary
   #     ary.keep_if                  -> Enumerator
   #
@@ -815,12 +818,11 @@ class Array
   #  a.permutation(0).to_a #=> [[]] # one permutation of length 0
   #  a.permutation(4).to_a #=> []   # no permutations of length 4
   def permutation(n=self.size, &block)
-    size = self.size
     return to_enum(:permutation, n) unless block
-    return if n > size
+    size = self.size
     if n == 0
-       yield []
-    else
+      yield []
+    elsif 0 < n && n <= size
       i = 0
       while i<size
         result = [self[i]]
@@ -835,6 +837,7 @@ class Array
         i += 1
       end
     end
+    self
   end
 
   ##
@@ -861,9 +864,8 @@ class Array
   #    a.combination(5).to_a  #=> []   # no combinations of length 5
 
   def combination(n, &block)
-    size = self.size
     return to_enum(:combination, n) unless block
-    return if n > size
+    size = self.size
     if n == 0
        yield []
     elsif n == 1
@@ -872,7 +874,7 @@ class Array
         yield [self[i]]
         i += 1
       end
-    else
+    elsif n <= size
       i = 0
       while i<size
         result = [self[i]]
@@ -882,6 +884,7 @@ class Array
         i += 1
       end
     end
+    self
   end
 
   ##
@@ -903,8 +906,8 @@ class Array
     column_count = nil
     self.each do |row|
       raise TypeError unless row.is_a?(Array)
-      column_count ||= row.count
-      raise IndexError, 'element size differs' unless column_count == row.count
+      column_count ||= row.size
+      raise IndexError, 'element size differs' unless column_count == row.size
     end
 
     Array.new(column_count) do |column_index|
@@ -936,4 +939,8 @@ class Array
     end
     h
   end
+
+  alias append push
+  alias prepend unshift
+  alias filter! select!
 end
index b6d9c9c..3ce5d82 100644 (file)
@@ -28,9 +28,8 @@ static mrb_value
 mrb_ary_assoc(mrb_state *mrb, mrb_value ary)
 {
   mrb_int i;
-  mrb_value v, k;
-
-  mrb_get_args(mrb, "o", &k);
+  mrb_value v;
+  mrb_value k = mrb_get_arg1(mrb);
 
   for (i = 0; i < RARRAY_LEN(ary); ++i) {
     v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);
@@ -59,13 +58,12 @@ static mrb_value
 mrb_ary_rassoc(mrb_state *mrb, mrb_value ary)
 {
   mrb_int i;
-  mrb_value v, value;
-
-  mrb_get_args(mrb, "o", &value);
+  mrb_value v;
+  mrb_value value = mrb_get_arg1(mrb);
 
   for (i = 0; i < RARRAY_LEN(ary); ++i) {
     v = RARRAY_PTR(ary)[i];
-    if (mrb_type(v) == MRB_TT_ARRAY &&
+    if (mrb_array_p(v) &&
         RARRAY_LEN(v) > 1 &&
         mrb_equal(mrb, RARRAY_PTR(v)[1], value))
       return v;
@@ -140,12 +138,11 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self)
   mrb_ary_modify(mrb, a);
 
   if (mrb_get_argc(mrb) == 1) {
-    mrb_value index;
+    mrb_value index = mrb_get_arg1(mrb);
 
-    mrb_get_args(mrb, "o|i", &index, &len);
     switch (mrb_type(index)) {
     case MRB_TT_RANGE:
-      if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == 1) {
+      if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
         goto delete_pos_len;
       }
       else {
@@ -194,7 +191,7 @@ mrb_mruby_array_ext_gem_init(mrb_state* mrb)
   mrb_define_method(mrb, a, "at",     mrb_ary_at,     MRB_ARGS_REQ(1));
   mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, a, "values_at", mrb_ary_values_at, MRB_ARGS_ANY());
-  mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang,   MRB_ARGS_ANY());
+  mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang,   MRB_ARGS_ARG(1,1));
 }
 
 void
index 853554b..2955ef3 100644 (file)
@@ -1,6 +1,23 @@
 ##
 # Array(Ext) Test
 
+def assert_permutation_combination(exp, receiver, meth, *args)
+  act = []
+  ret = receiver.__send__(meth, *args) { |v| act << v }
+  assert "assert_#{meth}" do
+    assert_equal(exp, act.sort)
+    assert_same(receiver, ret)
+  end
+end
+
+def assert_permutation(exp, receiver, *args)
+  assert_permutation_combination(exp, receiver, :permutation, *args)
+end
+
+def assert_combination(exp, receiver, *args)
+  assert_permutation_combination(exp, receiver, :combination, *args)
+end
+
 assert("Array#assoc") do
   s1 = [ "colors", "red", "blue", "green" ]
   s2 = [ "letters", "a", "b", "c" ]
@@ -76,6 +93,14 @@ assert("Array#union") do
   assert_equal [1, 2, 3, 4, 5], a.union(b,c)
 end
 
+assert("Array#difference") do
+  a = [1, 2, 3, 1, 6, 7]
+  b = [1, 4, 6]
+  c = [1, 5, 7]
+
+  assert_equal [2, 3], a.difference(b,c)
+end
+
 assert("Array#&") do
   a = [1, 2, 3, 1]
   b = [1, 4]
@@ -86,6 +111,14 @@ assert("Array#&") do
   assert_equal [1, 2, 3, 1], a
 end
 
+assert("Array#intersection") do
+  a = [1, 2, 3, 1, 8, 6, 7, 8]
+  b = [1, 4, 6, 8]
+  c = [1, 5, 7, 8]
+
+  assert_equal [1, 8], a.intersection(b,c)
+end
+
 assert("Array#flatten") do
   assert_equal [1, 2, "3", {4=>5}, :'6'],    [1, 2, "3", {4=>5}, :'6'].flatten
   assert_equal [1, 2, 3, 4, 5, 6], [1, 2,    [3, 4, 5], 6].flatten
@@ -162,12 +195,6 @@ assert("Array#reverse_each") do
     b << i
   end
   assert_equal [ "d", "c", "b", "a" ], b
-
-  if Object.const_defined?(:Enumerator)
-    assert_equal [ "d", "c", "b", "a" ], a.reverse_each.to_a
-  else
-    true
-  end
 end
 
 assert("Array#rotate") do
@@ -268,22 +295,9 @@ assert("Array#bsearch") do
   end
 end
 
-assert("Array#bsearch_index") do
-  # tested through Array#bsearch
-end
-
-assert("Array#delete_if") do
-  a = [1, 2, 3, 4, 5]
-  assert_equal [1, 2, 3, 4, 5], a.delete_if { false }
-  assert_equal [1, 2, 3, 4, 5], a
-
-  a = [1, 2, 3, 4, 5]
-  assert_equal [], a.delete_if { true }
-  assert_equal [], a
-
-  a = [ 1, 2, 3, 4, 5 ]
-  assert_equal [1, 2, 3], a.delete_if { |val| val > 3 }
-end
+# tested through Array#bsearch
+#assert("Array#bsearch_index") do
+#end
 
 assert("Array#keep_if") do
   a = [1, 2, 3, 4, 5]
@@ -369,30 +383,24 @@ end
 
 assert("Array#permutation") do
   a = [1, 2, 3]
-  assert_equal([[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]],
-               a.permutation.to_a)
-  assert_equal([[1],[2],[3]],
-               a.permutation(1).to_a)
-  assert_equal([[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]],
-               a.permutation(2).to_a)
-  assert_equal([[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]],
-               a.permutation(3).to_a)
-  assert_equal([[]], a.permutation(0).to_a)
-  assert_equal([], a.permutation(4).to_a)
+  assert_permutation([[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]], a)
+  assert_permutation([[1],[2],[3]], a, 1)
+  assert_permutation([[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]], a, 2)
+  assert_permutation([[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]], a, 3)
+  assert_permutation([[]], a, 0)
+  assert_permutation([], a, 4)
+  assert_permutation([], a, -1)
 end
 
 assert("Array#combination") do
   a = [1, 2, 3, 4]
-  assert_equal([[1],[2],[3],[4]],
-               a.combination(1).to_a)
-  assert_equal([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]],
-               a.combination(2).to_a)
-  assert_equal([[1,2,3],[1,2,4],[1,3,4],[2,3,4]],
-               a.combination(3).to_a)
-  assert_equal([[1,2,3,4]],
-               a.combination(4).to_a)
-  assert_equal([[]], a.combination(0).to_a)
-  assert_equal([], a.combination(5).to_a)
+  assert_combination([[1],[2],[3],[4]], a, 1)
+  assert_combination([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]], a, 2)
+  assert_combination([[1,2,3],[1,2,4],[1,3,4],[2,3,4]], a, 3)
+  assert_combination([[1,2,3,4]], a, 4)
+  assert_combination([[]], a, 0)
+  assert_combination([], a, 5)
+  assert_combination([], a, -1)
 end
 
 assert('Array#transpose') do
index 3a0a1b8..c56af43 100644 (file)
@@ -5,19 +5,22 @@ unless MRuby::Build.current.kind_of?(MRuby::CrossBuild)
     spec.author  = 'mruby developers'
     spec.summary = "#{name} command"
 
+    mruby_config_dir = "#{build.build_dir}/bin"
     mruby_config = name + (ENV['OS'] == 'Windows_NT' ? '.bat' : '')
-    mruby_config_path = "#{build.build_dir}/bin/#{mruby_config}"
+    mruby_config_path = "#{mruby_config_dir}/#{mruby_config}"
     make_cfg = "#{build.build_dir}/lib/libmruby.flags.mak"
     tmplt_path = "#{__dir__}/#{mruby_config}"
     build.bins << mruby_config
 
-    file mruby_config_path => [make_cfg, tmplt_path] do |t|
+    directory mruby_config_dir
+
+    file mruby_config_path => [mruby_config_dir, make_cfg, tmplt_path] do |t|
       config = Hash[File.readlines(make_cfg).map!(&:chomp).map! {|l|
         l.gsub('\\"', '"').split(' = ', 2).map! {|s| s.sub(/^(?=.)/, 'echo ')}
       }]
       tmplt = File.read(tmplt_path)
       File.write(t.name, tmplt.gsub(/(#{Regexp.union(*config.keys)})\b/, config))
-      FileUtils.chmod(0755, t.name)
+      chmod(0755, t.name)
     end
   end
 end
index 6675392..a840196 100644 (file)
@@ -1,9 +1,10 @@
 require 'open3'
 require 'tempfile'
+require 'strscan'
 
 class BinTest_MrubyBinDebugger
-  @debug1=false
-  @debug2=true
+#  @debug1=false
+#  @debug2=true
   def self.test(rubysource, testcase)
     script, bin = Tempfile.new(['test', '.rb']), Tempfile.new(['test', '.mrb'])
 
@@ -19,10 +20,20 @@ class BinTest_MrubyBinDebugger
 
     stdin_data = testcase.map{|t| t[:cmd]}.join("\n") << "\n"
 
+    prompt = /^\(#{Regexp.escape(script.path)}:\d+\) /
     ["bin/mrdb #{script.path}","bin/mrdb -b #{bin.path}"].each do |cmd|
       o, s = Open3.capture2(cmd, :stdin_data => stdin_data)
+      scanner = StringScanner.new(o)
+      scanner.skip_until(prompt)
+      testcase.each do |tc|
+        exp = tc[:exp]
+        if exp
+          act = scanner.scan_until(/\n/)
+          break unless assert_operator act, :start_with?, exp
+        end
+        scanner.skip_until(prompt)
+      end
 
-      exp_vals = testcase.map{|t| t.fetch(:exp, nil)}
 =begin
 if @debug1
   o.split("\n").each_with_index do |i,actual|
@@ -41,14 +52,6 @@ end
         assert_true actual.include?(exp) unless exp.nil?
       end
 =end
-      idx = 0
-      exp_vals.each do |exp|
-        next if exp.nil?
-        idx = o.index(exp, idx)
-        assert_false idx.nil?
-        break unless idx
-        idx += 1
-      end
     end
   end
 end
@@ -90,8 +93,8 @@ assert('mruby-bin-debugger(print) error') do
 
   # test case
   tc = []
-  tc << {:cmd=>"p (1+2",  :exp=>'$1 = SyntaxError'}
-  tc << {:cmd=>"p bar",   :exp=>'$2 = (eval):2: undefined method'}
+  tc << {:cmd=>"p (1+2",  :exp=>'$1 = line 1: syntax error'}
+  tc << {:cmd=>"p bar",   :exp=>'$2 = undefined method'}
 
   BinTest_MrubyBinDebugger.test(src, tc)
 end
@@ -588,7 +591,7 @@ SRC
   tc << {:cmd=>'p foo=[foo,bar,baz]', :exp=>'$2 = ["foo", "bar", "baz"]'}
 
   tc << {:cmd=>'p undefined=-1',      :exp=>'$3 = -1'}
-  tc << {:cmd=>'p "#{undefined}"',    :exp=>'$4 = (eval):2: undefined method'}
+  tc << {:cmd=>'p "#{undefined}"',    :exp=>'$4 = undefined method'}
 
   BinTest_MrubyBinDebugger.test(src, tc)
 end
@@ -626,7 +629,7 @@ SRC
   tc << {:cmd=>'p [a,b]',           :exp=>'$13 = [20, 10]'}
 
   tc << {:cmd=>'p undefined=-1',    :exp=>'$14 = -1'}
-  tc << {:cmd=>'p "#{undefined}"',  :exp=>'$15 = (eval):2: undefined method'}
+  tc << {:cmd=>'p "#{undefined}"',  :exp=>'$15 = undefined method'}
 
   BinTest_MrubyBinDebugger.test(src, tc)
 end
@@ -694,8 +697,7 @@ SRC
   tc << {:cmd=>'p [a,b]',           :exp=>'$13 = [20, 10]'}
 
   tc << {:cmd=>'p undefined=-1',    :exp=>'$14 = -1'}
-  tc << {:cmd=>'p "#{undefined}"',  :exp=>'$15 = (eval):2: undefined method'}
+  tc << {:cmd=>'p "#{undefined}"',  :exp=>'$15 = undefined method'}
 
   BinTest_MrubyBinDebugger.test(src, tc)
 end
-
index 513db4d..ceeb273 100644 (file)
@@ -95,7 +95,7 @@ check_file_lineno(mrb_state *mrb, struct mrb_irep *irep, const char *file, uint1
   for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
     const char *filename;
     info_file = irep->debug_info->files[f_idx];
-    filename = mrb_sym2name_len(mrb, info_file->filename_sym, NULL);
+    filename = mrb_sym_name_len(mrb, info_file->filename_sym, NULL);
     if (!strcmp(filename, file)) {
       result = MRB_DEBUG_BP_FILE_OK;
 
@@ -126,7 +126,7 @@ compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *cl
   mrb_debug_methodpoint *method_p;
   mrb_bool is_defined;
 
-  method_name = mrb_sym2name(mrb, method_sym);
+  method_name = mrb_sym_name(mrb, method_sym);
 
   method_p = &bp->point.methodpoint;
   if (strcmp(method_p->method_name, method_name) == 0) {
@@ -428,7 +428,7 @@ mrb_debug_disable_break_all(mrb_state *mrb, mrb_debug_context *dbg)
 }
 
 static mrb_bool
-check_start_pc_for_line(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, uint16_t line)
+check_start_pc_for_line(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, uint16_t line)
 {
   if (pc > irep->iseq) {
     if (line == mrb_debug_get_line(mrb, irep, pc - irep->iseq - 1)) {
index f888d14..e8702f4 100644 (file)
@@ -33,7 +33,7 @@ mrdb_check_syntax(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size
 mrb_value
 mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc, int direct_eval)
 {
-  void (*tmp)(struct mrb_state *, struct mrb_irep *, mrb_code *, mrb_value *);
+  void (*tmp)(struct mrb_state *, struct mrb_irep *, const mrb_code *, mrb_value *);
   mrb_value ruby_code;
   mrb_value s;
   mrb_value v;
@@ -74,7 +74,7 @@ mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t
     *exc = mrb_obj_is_kind_of(mrb, v, mrb->eException_class);
   }
 
-  s = mrb_funcall(mrb, v, "inspect", 0);
+  s = mrb_inspect(mrb, v);
 
   /* enable code_fetch_hook */
   mrb->code_fetch_hook = tmp;
index 25f0715..f78c1e1 100644 (file)
@@ -18,7 +18,6 @@ dbgcmd_print(mrb_state *mrb, mrdb_state *mrdb)
 {
   mrb_value expr;
   mrb_value result;
-  mrb_value s;
   uint8_t wcnt;
   int ai;
 
@@ -39,8 +38,9 @@ dbgcmd_print(mrb_state *mrb, mrdb_state *mrdb)
   result = mrb_debug_eval(mrb, mrdb->dbg, RSTRING_PTR(expr), RSTRING_LEN(expr), NULL, 0);
 
   /* $print_no = result */
-  s = mrb_str_cat_lit(mrb, result, "\0");
-  printf("$%lu = %s\n", (unsigned long)mrdb->print_no++, RSTRING_PTR(s));
+  printf("$%lu = ", (unsigned long)mrdb->print_no++);
+  fwrite(RSTRING_PTR(result), RSTRING_LEN(result), 1, stdout);
+  putc('\n', stdout);
 
   if (mrdb->print_no == 0) {
     mrdb->print_no = 1;
index 0034061..8fab3c2 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
 #include <ctype.h>
 
 #include <mruby.h>
@@ -505,7 +504,7 @@ get_and_parse_command(mrb_state *mrb, mrdb_state *mrdb)
 }
 
 static int32_t
-check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)
+check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
 {
   struct RClass* c;
   mrb_sym sym;
@@ -546,7 +545,7 @@ check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value
 }
 
 static void
-mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)
+mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
 {
   const char *file;
   int32_t line;
index 7b14a89..7c21de3 100644 (file)
@@ -105,7 +105,7 @@ typedef struct mrb_debug_breakpoint {
 typedef struct mrb_debug_context {
   struct mrb_irep *root_irep;
   struct mrb_irep *irep;
-  mrb_code *pc;
+  const mrb_code *pc;
   mrb_value *regs;
 
   const char *prvfile;
index f17f9c5..080b061 100644 (file)
@@ -6,6 +6,14 @@
 #ifndef MRDBCONF_H
 #define MRDBCONF_H
 
+#ifndef MRB_ENABLE_DEBUG_HOOK
+# error mruby-bin-debugger need 'MRB_ENABLE_DEBUG_HOOK' configuration in your 'build_config.rb'
+#endif
+
+#ifdef MRB_DISABLE_STDIO
+# error mruby-bin-debugger conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
+#endif
+
 /* configuration options: */
 /* maximum size for command buffer */
 #define MAX_COMMAND_LINE 1024
index 17b2ca1..a0eeaf4 100644 (file)
@@ -7,6 +7,11 @@
 */
 
 #include <mruby.h>
+
+#ifdef MRB_DISABLE_STDIO
+# error mruby-bin-mirb conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
+#endif
+
 #include <mruby/array.h>
 #include <mruby/proc.h>
 #include <mruby/compile.h>
@@ -17,7 +22,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
 #include <ctype.h>
 
 #include <signal.h>
@@ -240,7 +244,7 @@ usage(const char *name)
   };
   const char *const *p = usage_msg;
 
-  printf("Usage: %s [switches]\n", name);
+  printf("Usage: %s [switches] [programfile] [arguments]\n", name);
   while (*p)
     printf("  %s\n", *p++);
 }
@@ -406,6 +410,26 @@ ctrl_c_handler(int signo)
 }
 #endif
 
+#ifndef DISABLE_MIRB_UNDERSCORE
+void decl_lv_underscore(mrb_state *mrb, mrbc_context *cxt)
+{
+  struct RProc *proc;
+  struct mrb_parser_state *parser;
+
+  parser = mrb_parse_string(mrb, "_=nil", cxt);
+  if (parser == NULL) {
+    fputs("create parser state error\n", stderr);
+    mrb_close(mrb);
+    exit(EXIT_FAILURE);
+  }
+
+  proc = mrb_generate_code(mrb, parser);
+  mrb_vm_run(mrb, proc, mrb_top_self(mrb), 0);
+
+  mrb_parser_free(parser);
+}
+#endif
+
 int
 main(int argc, char **argv)
 {
@@ -471,6 +495,10 @@ main(int argc, char **argv)
 
   cxt = mrbc_context_new(mrb);
 
+#ifndef DISABLE_MIRB_UNDERSCORE
+  decl_lv_underscore(mrb, cxt);
+#endif
+
   /* Load libraries */
   for (i = 0; i < args.libc; i++) {
     FILE *lfp = fopen(args.libv[i], "r");
@@ -621,8 +649,8 @@ main(int argc, char **argv)
         /* adjust stack length of toplevel environment */
         if (mrb->c->cibase->env) {
           struct REnv *e = mrb->c->cibase->env;
-          if (e && MRB_ENV_STACK_LEN(e) < proc->body.irep->nlocals) {
-            MRB_ENV_SET_STACK_LEN(e, proc->body.irep->nlocals);
+          if (e && MRB_ENV_LEN(e) < proc->body.irep->nlocals) {
+            MRB_ENV_SET_LEN(e, proc->body.irep->nlocals);
           }
         }
         /* pass a proc for evaluation */
@@ -643,6 +671,9 @@ main(int argc, char **argv)
             result = mrb_any_to_s(mrb, result);
           }
           p(mrb, result, 1);
+#ifndef DISABLE_MIRB_UNDERSCORE
+          *(mrb->c->stack + 1) = result;
+#endif
         }
       }
       ruby_code[0] = '\0';
index 2fd9da7..4d984e7 100644 (file)
@@ -1,7 +1,11 @@
-#include <stdio.h>
+#include <mruby.h>
+
+#ifdef MRB_DISABLE_STDIO
+# error mruby-bin-mrbc conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
+#endif
+
 #include <stdlib.h>
 #include <string.h>
-#include <mruby.h>
 #include <mruby/compile.h>
 #include <mruby/dump.h>
 #include <mruby/proc.h>
@@ -32,8 +36,6 @@ usage(const char *name)
   "-v           print version number, then turn on verbose mode",
   "-g           produce debugging information",
   "-B<symbol>   binary <symbol> output in C language format",
-  "-e           generate little endian iseq data",
-  "-E           generate big endian iseq data",
   "--remove-lv  remove local variables",
   "--verbose    run at verbose mode",
   "--version    print the version",
@@ -50,19 +52,26 @@ usage(const char *name)
 static char *
 get_outfilename(mrb_state *mrb, char *infile, const char *ext)
 {
-  size_t infilelen;
-  size_t extlen;
+  size_t ilen, flen, elen;
   char *outfile;
-  char *p;
+  char *p = NULL;
 
-  infilelen = strlen(infile);
-  extlen = strlen(ext);
-  outfile = (char*)mrb_malloc(mrb, infilelen + extlen + 1);
-  memcpy(outfile, infile, infilelen + 1);
+  ilen = strlen(infile);
+  flen = ilen;
   if (*ext) {
-    if ((p = strrchr(outfile, '.')) == NULL)
-      p = outfile + infilelen;
-    memcpy(p, ext, extlen + 1);
+    elen = strlen(ext);
+    if ((p = strrchr(infile, '.'))) {
+      ilen = p - infile;
+    }
+    flen += elen;
+  }
+  else {
+    flen = ilen;
+  }
+  outfile = (char*)mrb_malloc(mrb, flen+1);
+  strncpy(outfile, infile, ilen+1);
+  if (p) {
+    strncpy(outfile+ilen, ext, elen+1);
   }
 
   return outfile;
@@ -71,7 +80,6 @@ get_outfilename(mrb_state *mrb, char *infile, const char *ext)
 static int
 parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
 {
-  char *outfile = NULL;
   static const struct mrbc_args args_zero = { 0 };
   int i;
 
@@ -86,7 +94,7 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
       case 'o':
         if (args->outfile) {
           fprintf(stderr, "%s: an output file is already specified. (%s)\n",
-                  args->prog, outfile);
+                  args->prog, args->outfile);
           return -1;
         }
         if (argv[i][2] == '\0' && argv[i+1]) {
@@ -121,10 +129,8 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
         args->flags |= DUMP_DEBUG_INFO;
         break;
       case 'E':
-        args->flags = DUMP_ENDIAN_BIG | (args->flags & ~DUMP_ENDIAN_MASK);
-        break;
       case 'e':
-        args->flags = DUMP_ENDIAN_LIL | (args->flags & ~DUMP_ENDIAN_MASK);
+        fprintf(stderr, "%s: -e/-E option no longer needed.\n", args->prog);
         break;
       case 'h':
         return -1;
@@ -157,10 +163,6 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
       break;
     }
   }
-  if (args->verbose && args->initname && (args->flags & DUMP_ENDIAN_MASK) == 0) {
-    fprintf(stderr, "%s: generating %s endian C file. specify -e/-E for cross compiling.\n",
-            args->prog, bigendian_p() ? "big" : "little");
-  }
   return i;
 }
 
@@ -184,7 +186,7 @@ partial_hook(struct mrb_parser_state *p)
     return -1;
   }
   fn = args->argv[args->idx++];
-  p->f = fopen(fn, "r");
+  p->f = fopen(fn, "rb");
   if (p->f == NULL) {
     fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, fn);
     return -1;
@@ -211,7 +213,7 @@ load_file(mrb_state *mrb, struct mrbc_args *args)
   }
   else {
     need_close = TRUE;
-    if ((infile = fopen(input, "r")) == NULL) {
+    if ((infile = fopen(input, "rb")) == NULL) {
       fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, input);
       return mrb_nil_value();
     }
index e8d1510..9887a28 100644 (file)
@@ -1,10 +1,18 @@
 require 'tempfile'
+require 'open3'
+
+def assert_mruby(exp_out, exp_err, exp_success, args)
+  out, err, stat = Open3.capture3(cmd("mruby"), *args)
+  assert "assert_mruby" do
+    assert_operator(exp_out, :===, out, "standard output")
+    assert_operator(exp_err, :===, err, "standard error")
+    assert_equal(exp_success, stat.success?, "exit success?")
+  end
+end
 
 assert('regression for #1564') do
-  o = `#{cmd('mruby')} -e #{shellquote('<<')} 2>&1`
-  assert_include o, "-e:1:2: syntax error"
-  o = `#{cmd('mruby')} -e #{shellquote('<<-')} 2>&1`
-  assert_include o, "-e:1:3: syntax error"
+  assert_mruby("", /\A-e:1:2: syntax error, .*\n\z/, false, %w[-e <<])
+  assert_mruby("", /\A-e:1:3: syntax error, .*\n\z/, false, %w[-e <<-])
 end
 
 assert('regression for #1572') do
@@ -31,6 +39,11 @@ assert '$0 value' do
   assert_equal '"-e"', `#{cmd('mruby')} -e #{shellquote('p $0')}`.chomp
 end
 
+assert 'ARGV value' do
+  assert_mruby(%{["ab", "cde"]\n}, "", true, %w[-e p(ARGV) ab cde])
+  assert_mruby("[]\n", "", true, %w[-e p(ARGV)])
+end
+
 assert('float literal') do
   script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb')
   File.write script.path, 'p [3.21, 2e308.infinite?, -2e308.infinite?]'
@@ -66,11 +79,22 @@ RUBY
   assert_equal 0, $?.exitstatus
 end
 
+assert('mruby -c option') do
+  assert_mruby("Syntax OK\n", "", true, ["-c", "-e", "p 1"])
+  assert_mruby("", /\A-e:1:7: syntax error, .*\n\z/, false, ["-c", "-e", "p 1; 1."])
+end
+
 assert('mruby -d option') do
-  o = `#{cmd('mruby')} -e #{shellquote('p $DEBUG')}`
-  assert_equal "false\n", o
-  o = `#{cmd('mruby')} -d -e #{shellquote('p $DEBUG')}`
-  assert_equal "true\n", o
+  assert_mruby("false\n", "", true, ["-e", "p $DEBUG"])
+  assert_mruby("true\n", "", true, ["-dep $DEBUG"])
+end
+
+assert('mruby -e option (no code specified)') do
+  assert_mruby("", /\A.*: No code specified for -e\n\z/, false, %w[-e])
+end
+
+assert('mruby -h option') do
+  assert_mruby(/\AUsage: #{Regexp.escape cmd("mruby")} .*/m, "", true, %w[-h])
 end
 
 assert('mruby -r option') do
@@ -95,3 +119,46 @@ EOS
   assert_equal 'hogeClass', `#{cmd('mruby')} -r #{lib.path} -r #{script.path} -e #{shellquote('print Hoge.class')}`
   assert_equal 0, $?.exitstatus
 end
+
+assert('mruby -r option (no library specified)') do
+  assert_mruby("", /\A.*: No library specified for -r\n\z/, false, %w[-r])
+end
+
+assert('mruby -r option (file not found)') do
+  assert_mruby("", /\A.*: Cannot open library file: .*\n\z/, false, %w[-r _no_exists_])
+end
+
+assert('mruby -v option') do
+  ver_re = '\Amruby \d+\.\d+\.\d+ \(\d+-\d+-\d+\)\n'
+  assert_mruby(/#{ver_re}\z/, "", true, %w[-v])
+  assert_mruby(/#{ver_re}^[^\n]*NODE.*\n:end\n\z/m, "", true, %w[-v -e p(:end)])
+end
+
+assert('mruby --verbose option') do
+  assert_mruby(/\A[^\n]*NODE.*\n:end\n\z/m, "", true, %w[--verbose -e p(:end)])
+end
+
+assert('mruby --') do
+  assert_mruby(%{["-x", "1"]\n}, "", true, %w[-e p(ARGV) -- -x 1])
+end
+
+assert('mruby invalid short option') do
+  assert_mruby("", /\A.*: invalid option -1 .*\n\z/, false, %w[-1])
+end
+
+assert('mruby invalid long option') do
+  assert_mruby("", /\A.*: invalid option --longopt .*\n\z/, false, %w[--longopt])
+end
+
+assert('unhandled exception') do
+  assert_mruby("", /\bEXCEPTION\b.*\n\z/, false, %w[-e raise("EXCEPTION")])
+end
+
+assert('program file not found') do
+  assert_mruby("", /\A.*: Cannot open program file: .*\n\z/, false, %w[_no_exists_])
+end
+
+assert('codegen error') do
+  code = "def f(#{(1..100).map{|n| "a#{n}"} * ","}); end"
+  assert_mruby("", /\Acodegen error:.*\n\z/, false, ["-e", code])
+end
index 280621e..1415013 100644 (file)
@@ -4,7 +4,6 @@ MRuby::Gem::Specification.new('mruby-bin-mruby') do |spec|
   spec.summary = 'mruby command'
   spec.bins = %w(mruby)
   spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
-  spec.add_dependency('mruby-error', :core => 'mruby-error')
   spec.add_test_dependency('mruby-print', :core => 'mruby-print')
 
   if build.cxx_exception_enabled?
index 498bede..e5c8f34 100644 (file)
@@ -1,39 +1,39 @@
-#include <stdio.h>
+#include <mruby.h>
+
+#ifdef MRB_DISABLE_STDIO
+# error mruby-bin-mruby conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
+#endif
+
 #include <stdlib.h>
 #include <string.h>
-#include <mruby.h>
 #include <mruby/array.h>
 #include <mruby/compile.h>
 #include <mruby/dump.h>
 #include <mruby/variable.h>
 
-#ifdef MRB_DISABLE_STDIO
-static void
-p(mrb_state *mrb, mrb_value obj)
-{
-  mrb_value val = mrb_inspect(mrb, obj);
-
-  fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
-  putc('\n', stdout);
-}
-#else
-#define p(mrb,obj) mrb_p(mrb,obj)
-#endif
-
 struct _args {
   FILE *rfp;
-  charcmdline;
+  char *cmdline;
   mrb_bool fname        : 1;
   mrb_bool mrbfile      : 1;
   mrb_bool check_syntax : 1;
   mrb_bool verbose      : 1;
+  mrb_bool version      : 1;
   mrb_bool debug        : 1;
   int argc;
-  char** argv;
+  char **argv;
   int libc;
   char **libv;
 };
 
+struct options {
+  int argc;
+  char **argv;
+  char *program;
+  char *opt;
+  char short_opt[2];
+};
+
 static void
 usage(const char *name)
 {
@@ -52,11 +52,69 @@ usage(const char *name)
   };
   const char *const *p = usage_msg;
 
-  printf("Usage: %s [switches] programfile\n", name);
+  printf("Usage: %s [switches] [programfile] [arguments]\n", name);
   while (*p)
     printf("  %s\n", *p++);
 }
 
+static void
+options_init(struct options *opts, int argc, char **argv)
+{
+  opts->argc = argc;
+  opts->argv = argv;
+  opts->program = *argv;
+  *opts->short_opt = 0;
+}
+
+static const char *
+options_opt(struct options *opts)
+{
+  /* concatenated short options (e.g. `-cv`) */
+  if (*opts->short_opt && *++opts->opt) {
+   short_opt:
+    opts->short_opt[0] = *opts->opt;
+    opts->short_opt[1] = 0;
+    return opts->short_opt;
+  }
+
+  while (++opts->argv, --opts->argc) {
+    opts->opt = *opts->argv;
+
+    /*  empty         || not start with `-`  || `-` */
+    if (!opts->opt[0] || opts->opt[0] != '-' || !opts->opt[1]) return NULL;
+
+    if (opts->opt[1] == '-') {
+      /* `--` */
+      if (!opts->opt[2]) {
+        ++opts->argv, --opts->argc;
+        return NULL;
+      }
+      /* long option */
+      opts->opt += 2;
+      *opts->short_opt = 0;
+      return opts->opt;
+    }
+    else {
+      /* short option */
+      ++opts->opt;
+      goto short_opt;
+    }
+  }
+  return NULL;
+}
+
+static const char *
+options_arg(struct options *opts)
+{
+  if (*opts->short_opt && opts->opt[1]) {
+    /* concatenated short option and option argument (e.g. `-rLIBRARY`) */
+    *opts->short_opt = 0;
+    return opts->opt + 1;
+  }
+  --opts->argc, ++opts->argv;
+  return opts->argc ? *opts->argv : NULL;
+}
+
 static char *
 dup_arg_item(mrb_state *mrb, const char *item)
 {
@@ -69,40 +127,24 @@ dup_arg_item(mrb_state *mrb, const char *item)
 static int
 parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
 {
-  char **origargv = argv;
   static const struct _args args_zero = { 0 };
+  struct options opts[1];
+  const char *opt, *item;
 
   *args = args_zero;
-
-  for (argc--,argv++; argc > 0; argc--,argv++) {
-    char *item;
-    if (argv[0][0] != '-') break;
-
-    if (strlen(*argv) <= 1) {
-      argc--; argv++;
-      args->rfp = stdin;
-      break;
-    }
-
-    item = argv[0] + 1;
-    switch (*item++) {
-    case 'b':
+  options_init(opts, argc, argv);
+  while ((opt = options_opt(opts))) {
+    if (strcmp(opt, "b") == 0) {
       args->mrbfile = TRUE;
-      break;
-    case 'c':
+    }
+    else if (strcmp(opt, "c") == 0) {
       args->check_syntax = TRUE;
-      break;
-    case 'd':
+    }
+    else if (strcmp(opt, "d") == 0) {
       args->debug = TRUE;
-      break;
-    case 'e':
-      if (item[0]) {
-        goto append_cmdline;
-      }
-      else if (argc > 1) {
-        argc--; argv++;
-        item = argv[0];
-append_cmdline:
+    }
+    else if (strcmp(opt, "e") == 0) {
+      if ((item = options_arg(opts))) {
         if (!args->cmdline) {
           args->cmdline = dup_arg_item(mrb, item);
         }
@@ -119,55 +161,65 @@ append_cmdline:
         }
       }
       else {
-        printf("%s: No code specified for -e\n", *origargv);
-        return EXIT_SUCCESS;
+        fprintf(stderr, "%s: No code specified for -e\n", opts->program);
+        return EXIT_FAILURE;
       }
-      break;
-    case 'r':
-      if (!item[0]) {
-        if (argc <= 1) {
-          printf("%s: No library specified for -r\n", *origargv);
-          return EXIT_FAILURE;
+    }
+    else if (strcmp(opt, "h") == 0) {
+      usage(opts->program);
+      exit(EXIT_SUCCESS);
+    }
+    else if (strcmp(opt, "r") == 0) {
+      if ((item = options_arg(opts))) {
+        if (args->libc == 0) {
+          args->libv = (char**)mrb_malloc(mrb, sizeof(char*));
         }
-        argc--; argv++;
-        item = argv[0];
-      }
-      if (args->libc == 0) {
-        args->libv = (char**)mrb_malloc(mrb, sizeof(char*));
+        else {
+          args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1));
+        }
+        args->libv[args->libc++] = dup_arg_item(mrb, item);
       }
       else {
-        args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1));
+        fprintf(stderr, "%s: No library specified for -r\n", opts->program);
+        return EXIT_FAILURE;
       }
-      args->libv[args->libc++] = dup_arg_item(mrb, item);
-      break;
-    case 'v':
-      if (!args->verbose) mrb_show_version(mrb);
-      args->verbose = TRUE;
-      break;
-    case '-':
-      if (strcmp((*argv) + 2, "version") == 0) {
+    }
+    else if (strcmp(opt, "v") == 0) {
+      if (!args->verbose) {
         mrb_show_version(mrb);
-        exit(EXIT_SUCCESS);
-      }
-      else if (strcmp((*argv) + 2, "verbose") == 0) {
-        args->verbose = TRUE;
-        break;
+        args->version = TRUE;
       }
-      else if (strcmp((*argv) + 2, "copyright") == 0) {
-        mrb_show_copyright(mrb);
-        exit(EXIT_SUCCESS);
-      }
-    default:
+      args->verbose = TRUE;
+    }
+    else if (strcmp(opt, "version") == 0) {
+      mrb_show_version(mrb);
+      exit(EXIT_SUCCESS);
+    }
+    else if (strcmp(opt, "verbose") == 0) {
+      args->verbose = TRUE;
+    }
+    else if (strcmp(opt, "copyright") == 0) {
+      mrb_show_copyright(mrb);
+      exit(EXIT_SUCCESS);
+    }
+    else {
+      fprintf(stderr, "%s: invalid option %s%s (-h will show valid options)\n",
+              opts->program, opt[1] ? "--" : "-", opt);
       return EXIT_FAILURE;
     }
   }
 
-  if (args->rfp == NULL && args->cmdline == NULL) {
-    if (*argv == NULL) args->rfp = stdin;
+  argc = opts->argc; argv = opts->argv;
+  if (args->cmdline == NULL) {
+    if (*argv == NULL) {
+      if (args->version) exit(EXIT_SUCCESS);
+      args->rfp = stdin;
+    }
     else {
-      args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
+      args->rfp = strcmp(argv[0], "-") == 0 ?
+        stdin : fopen(argv[0], args->mrbfile ? "rb" : "r");
       if (args->rfp == NULL) {
-        printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
+        fprintf(stderr, "%s: Cannot open program file: %s\n", opts->program, argv[0]);
         return EXIT_FAILURE;
       }
       args->fname = TRUE;
@@ -212,14 +264,13 @@ main(int argc, char **argv)
   mrb_sym zero_sym;
 
   if (mrb == NULL) {
-    fputs("Invalid mrb_state, exiting mruby\n", stderr);
+    fprintf(stderr, "%s: Invalid mrb_state, exiting mruby\n", *argv);
     return EXIT_FAILURE;
   }
 
   n = parse_args(mrb, argc, argv, &args);
   if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) {
     cleanup(mrb, &args);
-    usage(argv[0]);
     return n;
   }
   else {
@@ -258,7 +309,7 @@ main(int argc, char **argv)
     for (i = 0; i < args.libc; i++) {
       FILE *lfp = fopen(args.libv[i], args.mrbfile ? "rb" : "r");
       if (lfp == NULL) {
-        printf("Cannot open library file: %s\n", args.libv[i]);
+        fprintf(stderr, "%s: Cannot open library file: %s\n", *argv, args.libv[i]);
         mrbc_context_free(mrb, c);
         cleanup(mrb, &args);
         return EXIT_FAILURE;
@@ -289,19 +340,16 @@ main(int argc, char **argv)
     mrb_gc_arena_restore(mrb, ai);
     mrbc_context_free(mrb, c);
     if (mrb->exc) {
-      if (mrb_undef_p(v)) {
-        mrb_p(mrb, mrb_obj_value(mrb->exc));
-      }
-      else {
+      if (!mrb_undef_p(v)) {
         mrb_print_error(mrb);
       }
-      n = -1;
+      n = EXIT_FAILURE;
     }
     else if (args.check_syntax) {
-      printf("Syntax OK\n");
+      puts("Syntax OK");
     }
   }
   cleanup(mrb, &args);
 
-  return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+  return n;
 }
index fb78b0c..3d05238 100644 (file)
@@ -1,7 +1,11 @@
-#include <stdio.h>
+#include <mruby.h>
+
+#ifdef MRB_DISABLE_STDIO
+# error mruby-bin-strip conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
+#endif
+
 #include <stdlib.h>
 #include <string.h>
-#include <mruby.h>
 #include <mruby/irep.h>
 #include <mruby/dump.h>
 
index 705db99..b7b5e18 100644 (file)
@@ -5,14 +5,17 @@
 static mrb_value
 mrb_mod_name(mrb_state *mrb, mrb_value self)
 {
-  mrb_value name = mrb_class_path(mrb, mrb_class_ptr(self));
-  return mrb_nil_p(name)? name : mrb_str_dup(mrb, name);
+  mrb_value name =  mrb_class_path(mrb, mrb_class_ptr(self));
+  if (mrb_string_p(name)) {
+    MRB_SET_FROZEN_FLAG(mrb_basic_ptr(name));
+  }
+  return name;
 }
 
 static mrb_value
 mrb_mod_singleton_class_p(mrb_state *mrb, mrb_value self)
 {
-  return mrb_bool_value(mrb_type(self) == MRB_TT_SCLASS);
+  return mrb_bool_value(mrb_sclass_p(self));
 }
 
 /*
@@ -40,14 +43,15 @@ mrb_mod_module_exec(mrb_state *mrb, mrb_value self)
   const mrb_value *argv;
   mrb_int argc;
   mrb_value blk;
+  struct RClass *c;
 
-  mrb_get_args(mrb, "*&", &argv, &argc, &blk);
+  mrb_get_args(mrb, "*&!", &argv, &argc, &blk);
 
-  if (mrb_nil_p(blk)) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
+  c = mrb_class_ptr(self);
+  if (mrb->c->ci->acc < 0) {
+    return mrb_yield_with_class(mrb, blk, argc, argv, self, c);
   }
-
-  mrb->c->ci->target_class = mrb_class_ptr(self);
+  mrb->c->ci->target_class = c;
   return mrb_yield_cont(mrb, blk, self, argc, argv);
 }
 
index 927cc3a..c64ffc4 100644 (file)
@@ -102,12 +102,13 @@ codegen_error(codegen_scope *s, const char *message)
   while (s->prev) {
     codegen_scope *tmp = s->prev;
     mrb_free(s->mrb, s->iseq);
+    mrb_free(s->mrb, s->lines);
     mrb_pool_close(s->mpool);
     s = tmp;
   }
 #ifndef MRB_DISABLE_STDIO
   if (s->filename_sym && s->lineno) {
-    const char *filename = mrb_sym2name_len(s->mrb, s->filename_sym, NULL);
+    const char *filename = mrb_sym_name_len(s->mrb, s->filename_sym, NULL);
     fprintf(stderr, "codegen error:%s:%d: %s\n", filename, s->lineno, message);
   }
   else {
@@ -272,8 +273,7 @@ genop_W(codegen_scope *s, mrb_code i, uint32_t a)
 #define NOVAL  0
 #define VAL    1
 
-//static
-mrb_bool
+static mrb_bool
 no_optimize(codegen_scope *s)
 {
   if (s && s->parser && s->parser->no_optimize)
@@ -281,17 +281,8 @@ no_optimize(codegen_scope *s)
   return FALSE;
 }
 
-static
-mrb_bool
-on_eval(codegen_scope *s)
-{
-  if (s && s->parser && s->parser->on_eval)
-    return TRUE;
-  return FALSE;
-}
-
 struct mrb_insn_data
-mrb_decode_insn(mrb_code *pc)
+mrb_decode_insn(const mrb_code *pc)
 {
   struct mrb_insn_data data = { 0 };
   mrb_code insn = READ_B();
@@ -407,9 +398,6 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
   if (no_peephole(s)) {
   normal:
     genop_2(s, OP_MOVE, dst, src);
-    if (on_eval(s)) {
-      genop_0(s, OP_NOP);
-    }
     return;
   }
   else {
@@ -559,7 +547,7 @@ new_lit(codegen_scope *s, mrb_value val)
       mrb_int len;
       pv = &s->irep->pool[i];
 
-      if (mrb_type(*pv) != MRB_TT_STRING) continue;
+      if (!mrb_string_p(*pv)) continue;
       if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue;
       if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0)
         return i;
@@ -570,7 +558,7 @@ new_lit(codegen_scope *s, mrb_value val)
     for (i=0; i<s->irep->plen; i++) {
       mrb_float f1, f2;
       pv = &s->irep->pool[i];
-      if (mrb_type(*pv) != MRB_TT_FLOAT) continue;
+      if (!mrb_float_p(*pv)) continue;
       f1 = mrb_float(*pv);
       f2 = mrb_float(val);
       if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i;
@@ -599,7 +587,7 @@ new_lit(codegen_scope *s, mrb_value val)
 
   switch (mrb_type(val)) {
   case MRB_TT_STRING:
-    *pv = mrb_str_pool(s->mrb, val);
+    *pv = mrb_str_pool(s->mrb, RSTRING_PTR(val), RSTRING_LEN(val), RSTR_NOFREE_P(RSTRING(val)));
     break;
 
 #ifndef MRB_WITHOUT_FLOAT
@@ -674,6 +662,43 @@ lv_idx(codegen_scope *s, mrb_sym id)
   return 0;
 }
 
+static int
+search_upvar(codegen_scope *s, mrb_sym id, int *idx)
+{
+  struct RProc *u;
+  int lv = 0;
+  codegen_scope *up = s->prev;
+
+  while (up) {
+    *idx = lv_idx(up, id);
+    if (*idx > 0) {
+      return lv;
+    }
+    lv ++;
+    up = up->prev;
+  }
+
+  if (lv < 1) lv = 1;
+  u = s->parser->upper;
+  while (u && !MRB_PROC_CFUNC_P(u)) {
+    struct mrb_irep *ir = u->body.irep;
+    uint_fast16_t n = ir->nlocals;
+    const struct mrb_locals *v = ir->lv;
+    for (; n > 1; n --, v ++) {
+      if (v->name == id) {
+        *idx = v->r;
+        return lv - 1;
+      }
+    }
+    if (MRB_PROC_SCOPE_P(u)) break;
+    u = u->upper;
+    lv ++;
+  }
+
+  codegen_error(s, "Can't found local variables");
+  return -1; /* not reached */
+}
+
 static void
 for_body(codegen_scope *s, node *tree)
 {
@@ -686,9 +711,6 @@ for_body(codegen_scope *s, node *tree)
   codegen(s, tree->cdr->car, VAL);
   /* generate loop-block */
   s = scope_new(s->mrb, s, NULL);
-  if (s == NULL) {
-    raise_error(prev, "unexpected scope");
-  }
 
   push();                       /* push for a block parameter */
 
@@ -724,9 +746,6 @@ lambda_body(codegen_scope *s, node *tree, int blk)
 {
   codegen_scope *parent = s;
   s = scope_new(s->mrb, s, tree->car);
-  if (s == NULL) {
-    raise_error(parent, "unexpected scope");
-  }
 
   s->mscope = !blk;
 
@@ -777,7 +796,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
     s->ainfo = (((ma+oa) & 0x3f) << 7) /* (12bits = 5:1:5:1) */
       | ((ra & 0x1) << 6)
       | ((pa & 0x1f) << 1)
-      | (kd & 0x1);
+      | ((ka | kd) != 0 ? 0x01 : 0x00);
     genop_W(s, OP_ENTER, a);
     /* generate jump table for optional arguments initializer */
     pos = new_label(s);
@@ -792,12 +811,19 @@ lambda_body(codegen_scope *s, node *tree, int blk)
     i = 0;
     while (opt) {
       int idx;
+      mrb_sym id = nsym(opt->car->car);
 
       dispatch(s, pos+i*3+1);
       codegen(s, opt->car->cdr, VAL);
       pop();
-      idx = lv_idx(s, nsym(opt->car->car));
-      gen_move(s, idx, cursp(), 0);
+      idx = lv_idx(s, id);
+      if (idx > 0) {
+        gen_move(s, idx, cursp(), 0);
+      }
+      else {
+        int lv = search_upvar(s, id, &idx);
+        genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
+      }
       i++;
       opt = opt->cdr;
     }
@@ -824,11 +850,19 @@ lambda_body(codegen_scope *s, node *tree, int blk)
         mrb_assert(nint(kwd->car) == NODE_KW_ARG);
 
         if (def_arg) {
+          int idx;
           genop_2(s, OP_KEY_P, lv_idx(s, kwd_sym), new_sym(s, kwd_sym));
           jmpif_key_p = genjmp2(s, OP_JMPIF, lv_idx(s, kwd_sym), 0, 0);
           codegen(s, def_arg, VAL);
           pop();
-          gen_move(s, lv_idx(s, kwd_sym), cursp(), 0);
+          idx = lv_idx(s, kwd_sym);
+          if (idx > 0) {
+            gen_move(s, idx, cursp(), 0);
+          }
+          else {
+            int lv = search_upvar(s, kwd_sym, &idx);
+            genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
+          }
           jmp_def_set = genjmp(s, OP_JMP, 0);
           dispatch(s, jmpif_key_p);
         }
@@ -888,9 +922,6 @@ static int
 scope_body(codegen_scope *s, node *tree, int val)
 {
   codegen_scope *scope = scope_new(s->mrb, s, tree->car);
-  if (scope == NULL) {
-    codegen_error(s, "unexpected scope");
-  }
 
   codegen(scope, tree->cdr, VAL);
   gen_return(scope, OP_RETURN, scope->sp-1);
@@ -922,7 +953,7 @@ attrsym(codegen_scope *s, mrb_sym a)
   mrb_int len;
   char *name2;
 
-  name = mrb_sym2name_len(s->mrb, a, &len);
+  name = mrb_sym_name_len(s->mrb, a, &len);
   name2 = (char *)codegen_palloc(s,
                                  (size_t)len
                                  + 1 /* '=' */
@@ -956,7 +987,12 @@ gen_values(codegen_scope *s, node *t, int val, int extra)
         }
         else {
           pop_n(n);
-          genop_2(s, OP_ARRAY, cursp(), n);
+          if (n == 0 && is_splat) {
+            genop_1(s, OP_LOADNIL, cursp());
+          }
+          else {
+            genop_2(s, OP_ARRAY, cursp(), n);
+          }
           push();
           codegen(s, t->car, VAL);
           pop(); pop();
@@ -1041,7 +1077,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
   pop_n(n+1);
   {
     mrb_int symlen;
-    const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen);
+    const char *symname = mrb_sym_name_len(s->mrb, sym, &symlen);
 
     if (!noop && symlen == 1 && symname[0] == '+' && n == 1)  {
       gen_addsub(s, OP_ADD, cursp());
@@ -1107,25 +1143,18 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val)
     if (idx > 0) {
       if (idx != sp) {
         gen_move(s, idx, sp, val);
-        if (val && on_eval(s)) genop_0(s, OP_NOP);
       }
       break;
     }
     else {                      /* upvar */
-      int lv = 0;
-      codegen_scope *up = s->prev;
-
-      while (up) {
-        idx = lv_idx(up, nsym(tree));
-        if (idx > 0) {
-          genop_3(s, OP_SETUPVAR, sp, idx, lv);
-          break;
-        }
-        lv++;
-        up = up->prev;
-      }
+      int lv = search_upvar(s, nsym(tree), &idx);
+      genop_3(s, OP_SETUPVAR, sp, idx, lv);
     }
     break;
+  case NODE_NVAR:
+    idx = nint(tree);
+    codegen_error(s, "Can't assign to numbered parameter");
+    break;
   case NODE_IVAR:
     idx = new_sym(s, nsym(tree));
     genop_2(s, OP_SETIV, sp, idx);
@@ -1401,7 +1430,7 @@ codegen(codegen_scope *s, node *tree, int val)
   }
   if (s->irep && s->filename_index != tree->filename_index) {
     mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index);
-    const char *filename = mrb_sym2name_len(s->mrb, fname, NULL);
+    const char *filename = mrb_sym_name_len(s->mrb, fname, NULL);
 
     mrb_debug_info_append_file(s->mrb, s->irep->debug_info,
                                filename, s->lines, s->debug_start_pos, s->pc);
@@ -1553,7 +1582,7 @@ codegen(codegen_scope *s, node *tree, int val)
 
   case NODE_IF:
     {
-      int pos1, pos2;
+      int pos1, pos2, nil_p = FALSE;
       node *elsepart = tree->cdr->cdr->car;
 
       if (!tree->car) {
@@ -1570,32 +1599,59 @@ codegen(codegen_scope *s, node *tree, int val)
       case NODE_NIL:
         codegen(s, elsepart, val);
         goto exit;
+      case NODE_CALL:
+        {
+          node *n = tree->car->cdr;
+          mrb_sym mid = nsym(n->cdr->car);
+          mrb_sym mnil = mrb_intern_lit(s->mrb, "nil?");
+          if (mid == mnil && n->cdr->cdr->car == NULL) {
+            nil_p = TRUE;
+            codegen(s, n->car, VAL);
+          }
+        }
+        break;
+      }
+      if (!nil_p) {
+        codegen(s, tree->car, VAL);
       }
-      codegen(s, tree->car, VAL);
       pop();
-      pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
-
-      codegen(s, tree->cdr->car, val);
-      if (elsepart) {
+      if (val || tree->cdr->car) {
+        if (nil_p) {
+          pos2 = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
+          pos1 = genjmp(s, OP_JMP, 0);
+          dispatch(s, pos2);
+        }
+        else {
+          pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
+        }
+        codegen(s, tree->cdr->car, val);
         if (val) pop();
-        pos2 = genjmp(s, OP_JMP, 0);
-        dispatch(s, pos1);
-        codegen(s, elsepart, val);
-        dispatch(s, pos2);
-      }
-      else {
-        if (val) {
-          pop();
+        if (elsepart || val) {
           pos2 = genjmp(s, OP_JMP, 0);
           dispatch(s, pos1);
-          genop_1(s, OP_LOADNIL, cursp());
+          codegen(s, elsepart, val);
           dispatch(s, pos2);
-          push();
         }
         else {
           dispatch(s, pos1);
         }
       }
+      else {                    /* empty then-part */
+        if (elsepart) {
+          if (nil_p) {
+            pos1 = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
+          }
+          else {
+            pos1 = genjmp2(s, OP_JMPIF, cursp(), 0, val);
+          }
+          codegen(s, elsepart, val);
+          dispatch(s, pos1);
+        }
+        else if (val && !nil_p) {
+          genop_1(s, OP_LOADNIL, cursp());
+          push();
+        }
+      }
     }
     break;
 
@@ -1833,7 +1889,7 @@ codegen(codegen_scope *s, node *tree, int val)
           len++;
         }
         tree = tree->cdr;
-        if (val && len == 255) {
+        if (val && cursp() > 127) {
           pop_n(len*2);
           if (!update) {
             genop_2(s, OP_HASH, cursp(), len);
@@ -1955,7 +2011,7 @@ codegen(codegen_scope *s, node *tree, int val)
     {
       mrb_sym sym = nsym(tree->cdr->car);
       mrb_int len;
-      const char *name = mrb_sym2name_len(s->mrb, sym, &len);
+      const char *name = mrb_sym_name_len(s->mrb, sym, &len);
       int idx, callargs = -1, vsp = -1;
 
       if ((len == 2 && name[0] == '|' && name[1] == '|') &&
@@ -2297,26 +2353,25 @@ codegen(codegen_scope *s, node *tree, int val)
 
       if (idx > 0) {
         gen_move(s, cursp(), idx, val);
-        if (val && on_eval(s)) genop_0(s, OP_NOP);
       }
       else {
-        int lv = 0;
-        codegen_scope *up = s->prev;
-
-        while (up) {
-          idx = lv_idx(up, nsym(tree));
-          if (idx > 0) {
-            genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
-            break;
-          }
-          lv++;
-          up = up->prev;
-        }
+        int lv = search_upvar(s, nsym(tree), &idx);
+        genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
       }
       push();
     }
     break;
 
+  case NODE_NVAR:
+    if (val) {
+      int idx = nint(tree);
+
+      gen_move(s, cursp(), idx, val);
+
+      push();
+    }
+    break;
+
   case NODE_GVAR:
     {
       int sym = new_sym(s, nsym(tree));
@@ -2353,10 +2408,6 @@ codegen(codegen_scope *s, node *tree, int val)
     }
     break;
 
-  case NODE_DEFINED:
-    codegen(s, tree, val);
-    break;
-
   case NODE_BACK_REF:
     if (val) {
       char buf[] = {'$', nchar(tree)};
@@ -2373,7 +2424,7 @@ codegen(codegen_scope *s, node *tree, int val)
       mrb_value str;
       int sym;
 
-      str = mrb_format(mrb, "$%S", mrb_fixnum_value(nint(tree)));
+      str = mrb_format(mrb, "$%d", nint(tree));
       sym = new_sym(s, mrb_intern_str(mrb, str));
       genop_2(s, OP_GETGV, cursp(), sym);
       push();
@@ -2406,12 +2457,20 @@ codegen(codegen_scope *s, node *tree, int val)
       else
 #endif
       {
-        if (i == -1) genop_1(s, OP_LOADI__1, cursp());
-        else if (i < 0) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i);
+        if (i < 0) {
+          if (i == -1) genop_1(s, OP_LOADI__1, cursp());
+          else if (i >= -0xff) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); 
+          else if (i >= -0x8000) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i);
+          else goto lit_int;
+        }
         else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, cursp());
-        else if (i <= 0xffff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i);
+        else if (i <= 0xff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i);
+        else if (i <= 0x7fff) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i);
         else {
-          int off = new_lit(s, mrb_fixnum_value(i));
+          int off;
+
+        lit_int:
+          off = new_lit(s, mrb_fixnum_value(i));
           genop_2(s, OP_LOADL, cursp(), off);
         }
       }
@@ -2467,9 +2526,12 @@ codegen(codegen_scope *s, node *tree, int val)
           else {
 #endif
             if (i == -1) genop_1(s, OP_LOADI__1, cursp());
-            else if (i >= -0xffff) {
+            else if (i >= -0xff) {
               genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i);
             }
+            else if (i >= -0x8000) {
+              genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i);
+            }
             else {
               int off = new_lit(s, mrb_fixnum_value(i));
               genop_2(s, OP_LOADL, cursp(), off);
@@ -2944,7 +3006,11 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
   mrb_pool *pool = mrb_pool_open(mrb);
   codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope));
 
-  if (!p) return NULL;
+  if (!p) {
+    if (prev)
+      codegen_error(prev, "unexpected scope");
+    return NULL;
+  }
   *p = codegen_scope_zero;
   p->mrb = mrb;
   p->mpool = pool;
@@ -3020,6 +3086,9 @@ scope_finish(codegen_scope *s)
   mrb_state *mrb = s->mrb;
   mrb_irep *irep = s->irep;
 
+  if (s->nlocals >= 0x3ff) {
+    codegen_error(s, "too many local variables");
+  }
   irep->flags = 0;
   if (s->iseq) {
     irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
@@ -3030,7 +3099,7 @@ scope_finish(codegen_scope *s)
   irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen);
   if (s->filename_sym) {
     mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index);
-    const char *filename = mrb_sym2name_len(s->mrb, fname, NULL);
+    const char *filename = mrb_sym_name_len(s->mrb, fname, NULL);
 
     mrb_debug_info_append_file(s->mrb, s->irep->debug_info,
                                filename, s->lines, s->debug_start_pos, s->pc);
@@ -3134,9 +3203,6 @@ generate_code(mrb_state *mrb, parser_state *p, int val)
   struct RProc *proc;
   struct mrb_jmpbuf *prev_jmp = mrb->jmp;
 
-  if (!scope) {
-    return NULL;
-  }
   scope->mrb = mrb;
   scope->parser = p;
   scope->filename_sym = p->filename_sym;
index 9cb8660..a60ecd1 100644 (file)
@@ -1,8 +1,5 @@
 %{
 struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
-const struct kwtable *mrb_reserved_word(const char *, unsigned int);
-static const struct kwtable *reserved_word(const char *, unsigned int);
-#define mrb_reserved_word(str, len) reserved_word(str, len)
 %}
 
 struct kwtable;
index 2ff2664..872bf40 100644 (file)
@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.4 */
+/* ANSI-C code produced by gperf version 3.1 */
 /* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' /home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords  */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
       && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
       && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
 /* The character set is not based on ISO-646.  */
-#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
 #endif
 
 #line 1 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
 
 struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
-const struct kwtable *mrb_reserved_word(const char *, unsigned int);
-static const struct kwtable *reserved_word(const char *, unsigned int);
-#define mrb_reserved_word(str, len) reserved_word(str, len)
-#line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 5 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
 struct kwtable;
 
 #define TOTAL_KEYWORDS 40
@@ -52,7 +49,7 @@ inline
 #endif
 #endif
 static unsigned int
-hash (const char *str, unsigned int len)
+hash (register const char *str, register size_t len)
 {
   static const unsigned char asso_values[] =
     {
@@ -83,7 +80,7 @@ hash (const char *str, unsigned int len)
       51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
       51, 51, 51, 51, 51, 51
     };
-  int hval = len;
+  register unsigned int hval = len;
 
   switch (hval)
     {
@@ -98,109 +95,103 @@ hash (const char *str, unsigned int len)
   return hval + asso_values[(unsigned char)str[len - 1]];
 }
 
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
 const struct kwtable *
-mrb_reserved_word (const char *str, unsigned int len)
+mrb_reserved_word (register const char *str, register size_t len)
 {
   static const struct kwtable wordlist[] =
     {
       {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-#line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"break",        {keyword_break,       keyword_break},       EXPR_MID},
-#line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"else",         {keyword_else,        keyword_else},        EXPR_BEG},
-#line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"nil",          {keyword_nil,         keyword_nil},         EXPR_END},
-#line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"ensure",       {keyword_ensure,      keyword_ensure},      EXPR_BEG},
-#line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"end",          {keyword_end,         keyword_end},         EXPR_END},
-#line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"then",         {keyword_then,        keyword_then},        EXPR_BEG},
-#line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"not",          {keyword_not,         keyword_not},         EXPR_ARG},
-#line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"false",        {keyword_false,       keyword_false},       EXPR_END},
-#line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"self",         {keyword_self,        keyword_self},        EXPR_END},
-#line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"elsif",        {keyword_elsif,       keyword_elsif},       EXPR_VALUE},
-#line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"rescue",       {keyword_rescue,      modifier_rescue},     EXPR_MID},
-#line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"true",         {keyword_true,        keyword_true},        EXPR_END},
-#line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"until",        {keyword_until,       modifier_until},      EXPR_VALUE},
-#line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"unless",       {keyword_unless,      modifier_unless},     EXPR_VALUE},
-#line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"return",       {keyword_return,      keyword_return},      EXPR_MID},
-#line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"def",          {keyword_def,         keyword_def},         EXPR_FNAME},
-#line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"and",          {keyword_and,         keyword_and},         EXPR_VALUE},
-#line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"do",           {keyword_do,          keyword_do},          EXPR_BEG},
-#line 49 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"yield",        {keyword_yield,       keyword_yield},       EXPR_ARG},
-#line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"for",          {keyword_for,         keyword_for},         EXPR_VALUE},
-#line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"undef",        {keyword_undef,       keyword_undef},       EXPR_FNAME},
-#line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"or",           {keyword_or,          keyword_or},          EXPR_VALUE},
-#line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"in",           {keyword_in,          keyword_in},          EXPR_VALUE},
-#line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"when",         {keyword_when,        keyword_when},        EXPR_VALUE},
-#line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"retry",        {keyword_retry,       keyword_retry},       EXPR_END},
-#line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"if",           {keyword_if,          modifier_if},         EXPR_VALUE},
-#line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"case",         {keyword_case,        keyword_case},        EXPR_VALUE},
-#line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"redo",         {keyword_redo,        keyword_redo},        EXPR_END},
-#line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"next",         {keyword_next,        keyword_next},        EXPR_MID},
-#line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"super",        {keyword_super,       keyword_super},       EXPR_ARG},
-#line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"module",       {keyword_module,      keyword_module},      EXPR_VALUE},
-#line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"begin",        {keyword_begin,       keyword_begin},       EXPR_BEG},
-#line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 9 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"__LINE__",     {keyword__LINE__,     keyword__LINE__},     EXPR_END},
-#line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"__FILE__",     {keyword__FILE__,     keyword__FILE__},     EXPR_END},
-#line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 7 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
-#line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"END",          {keyword_END,         keyword_END},         EXPR_END},
-#line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"alias",        {keyword_alias,       keyword_alias},       EXPR_FNAME},
-#line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"BEGIN",        {keyword_BEGIN,       keyword_BEGIN},       EXPR_END},
       {""},
-#line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"class",        {keyword_class,       keyword_class},       EXPR_CLASS},
       {""}, {""},
-#line 48 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
       {"while",        {keyword_while,       modifier_while},      EXPR_VALUE}
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
     {
-      int key = hash (str, len);
+      register unsigned int key = hash (str, len);
 
-      if (key <= MAX_HASH_VALUE && key >= 0)
+      if (key <= MAX_HASH_VALUE)
         {
-          const char *s = wordlist[key].name;
+          register const char *s = wordlist[key].name;
 
           if (*str == *s && !strcmp (str + 1, s + 1))
             return &wordlist[key];
@@ -208,4 +199,5 @@ mrb_reserved_word (const char *str, unsigned int len)
     }
   return 0;
 }
-#line 50 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+
index 219bdda..a57b7bd 100644 (file)
@@ -51,6 +51,7 @@ enum node_type {
   NODE_IVAR,
   NODE_CONST,
   NODE_CVAR,
+  NODE_NVAR,
   NODE_NTH_REF,
   NODE_BACK_REF,
   NODE_MATCH,
index 88d9ea4..23fad6e 100644 (file)
@@ -9,14 +9,7 @@
 #ifdef PARSER_DEBUG
 # define YYDEBUG 1
 #endif
-#define YYERROR_VERBOSE 1
-/*
- * Force yacc to use our memory management.  This is a little evil because
- * the macros assume that "parser_state *p" is in scope
- */
-#define YYMALLOC(n)    mrb_malloc(p->mrb, (n))
-#define YYFREE(o)      mrb_free(p->mrb, (o))
-#define YYSTACK_USE_ALLOCA 0
+#define YYSTACK_USE_ALLOCA 1
 
 #include <ctype.h>
 #include <errno.h>
@@ -27,6 +20,7 @@
 #include <mruby/proc.h>
 #include <mruby/error.h>
 #include <mruby/throw.h>
+#include <mruby/string.h>
 #include "node.h"
 
 #define YYLEX_PARAM p
@@ -76,6 +70,9 @@ typedef unsigned int stack_type;
 #define nint(x) ((node*)(intptr_t)(x))
 #define intn(x) ((int)(intptr_t)(x))
 
+#define NUM_SUFFIX_R   (1<<0)
+#define NUM_SUFFIX_I   (1<<1)
+
 static inline mrb_sym
 intern_cstr_gen(parser_state *p, const char *s)
 {
@@ -90,12 +87,7 @@ intern_gen(parser_state *p, const char *s, size_t len)
 }
 #define intern(s,len) intern_gen(p,(s),(len))
 
-static inline mrb_sym
-intern_gen_c(parser_state *p, const char c)
-{
-  return mrb_intern(p->mrb, &c, 1);
-}
-#define intern_c(c) intern_gen_c(p,(c))
+#define intern_lit(s) mrb_intern_lit(p->mrb, s)
 
 static void
 cons_free_gen(parser_state *p, node *cons)
@@ -189,12 +181,11 @@ append_gen(parser_state *p, node *a, node *b)
   node *c = a;
 
   if (!a) return b;
+  if (!b) return a;
   while (c->cdr) {
     c = c->cdr;
   }
-  if (b) {
-    c->cdr = b;
-  }
+  c->cdr = b;
   return a;
 }
 #define append(a,b) append_gen(p,(a),(b))
@@ -220,6 +211,26 @@ parser_strdup(parser_state *p, const char *s)
 #undef strdup
 #define strdup(s) parser_strdup(p, s)
 
+static void
+dump_int(uint16_t i, char *s)
+{
+  char *p = s;
+  char *t = s;
+
+  while (i > 0) {
+    *p++ = (i % 10)+'0';
+    i /= 10;
+  }
+  if (p == s) *p++ = '0';
+  *p = 0;
+  p--;  /* point the last char */
+  while (t < p) {
+    char c = *t;
+    *t++ = *p;
+    *p-- = c;
+  }
+}
+
 /* xxx ----------------------------- */
 
 static node*
@@ -254,6 +265,7 @@ local_unnest(parser_state *p)
 static mrb_bool
 local_var_p(parser_state *p, mrb_sym sym)
 {
+  struct RProc *u;
   node *l = p->locals;
 
   while (l) {
@@ -264,6 +276,18 @@ local_var_p(parser_state *p, mrb_sym sym)
     }
     l = l->cdr;
   }
+
+  u = p->upper;
+  while (u && !MRB_PROC_CFUNC_P(u)) {
+    struct mrb_irep *ir = u->body.irep;
+    uint_fast16_t n = ir->nlocals;
+    const struct mrb_locals *v = ir->lv;
+    for (; n > 1; n --, v ++) {
+      if (v->name == sym) return TRUE;
+    }
+    if (MRB_PROC_SCOPE_P(u)) break;
+    u = u->upper;
+  }
   return FALSE;
 }
 
@@ -303,6 +327,24 @@ locals_node(parser_state *p)
   return p->locals ? p->locals->car : NULL;
 }
 
+static void
+nvars_nest(parser_state *p)
+{
+  p->nvars = cons(nint(0), p->nvars);
+}
+
+static void
+nvars_block(parser_state *p)
+{
+  p->nvars = cons(nint(-2), p->nvars);
+}
+
+static void
+nvars_unnest(parser_state *p)
+{
+  p->nvars = p->nvars->cdr;
+}
+
 /* (:scope (vars..) (prog...)) */
 static node*
 new_scope(parser_state *p, node *body)
@@ -637,6 +679,16 @@ new_cvar(parser_state *p, mrb_sym sym)
   return cons((node*)NODE_CVAR, nsym(sym));
 }
 
+/* (:nvar . a) */
+static node*
+new_nvar(parser_state *p, int num)
+{
+  int nvars = intn(p->nvars->car);
+
+  p->nvars->car = nint(nvars > num ? nvars : num);
+  return cons((node*)NODE_NVAR, nint(num));
+}
+
 /* (:const . a) */
 static node*
 new_const(parser_state *p, mrb_sym sym)
@@ -715,6 +767,15 @@ local_add_margs(parser_state *p, node *n)
   }
 }
 
+static void
+local_add_lv(parser_state *p, node *lv)
+{
+  while (lv) {
+    local_add_f(p, sym(lv->car));
+    lv = lv->cdr;
+  }
+}
+
 /* (m o r m2 tail) */
 /* m: (a b c) */
 /* o: ((a . e1) (b . e2)) */
@@ -731,6 +792,12 @@ new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, node *tail
   n = cons(m2, tail);
   n = cons(nsym(rest), n);
   n = cons(opt, n);
+  while (opt) {
+    /* opt: (sym . (opt . lv)) -> (sym . opt) */
+    local_add_lv(p, opt->car->cdr->cdr);
+    opt->car->cdr = opt->car->cdr->car;
+    opt = opt->cdr;
+  }
   return cons(m, n);
 }
 
@@ -746,15 +813,17 @@ new_args_tail(parser_state *p, node *kws, node *kwrest, mrb_sym blk)
 
   local_add_blk(p, blk);
 
-  // allocate register for keywords arguments
-  // order is for Proc#parameters
+  /* allocate register for keywords arguments */
+  /* order is for Proc#parameters */
   for (k = kws; k; k = k->cdr) {
-    if (!k->car->cdr->cdr->car) { // allocate required keywords
+    if (!k->car->cdr->cdr->car) { /* allocate required keywords */
       local_add_f(p, sym(k->car->cdr->car));
     }
   }
   for (k = kws; k; k = k->cdr) {
-    if (k->car->cdr->cdr->car) { // allocate keywords with default
+    if (k->car->cdr->cdr->car) { /* allocate keywords with default */
+      local_add_lv(p, k->car->cdr->cdr->car->cdr);
+      k->car->cdr->cdr->car = k->car->cdr->cdr->car->car;
       local_add_f(p, sym(k->car->cdr->car));
     }
   }
@@ -770,6 +839,13 @@ new_kw_arg(parser_state *p, mrb_sym kw, node *def_arg)
   return list3((node*)NODE_KW_ARG, nsym(kw), def_arg);
 }
 
+/* (:kw_rest_args . a) */
+static node*
+new_kw_rest_args(parser_state *p, node *a)
+{
+  return cons((node*)NODE_KW_REST_ARGS, a);
+}
+
 /* (:block_arg . a) */
 static node*
 new_block_arg(parser_state *p, node *a)
@@ -777,10 +853,41 @@ new_block_arg(parser_state *p, node *a)
   return cons((node*)NODE_BLOCK_ARG, a);
 }
 
+static node*
+setup_numparams(parser_state *p, node *a)
+{
+  int nvars = intn(p->nvars->car);
+  if (nvars > 0) {
+    int i;
+    mrb_sym sym;
+    // m || opt || rest || tail
+    if (a && (a->car || (a->cdr && a->cdr->car) || (a->cdr->cdr && a->cdr->cdr->car) || (a->cdr->cdr->cdr->cdr && a->cdr->cdr->cdr->cdr->car))) {
+      yyerror(p, "ordinary parameter is defined");
+    }
+    else if (p->locals) {
+      /* p->locals should not be NULL unless error happens before the point */
+      node* args = 0;
+      for (i = nvars; i > 0; i--) {
+        char buf[3];
+
+        buf[0] = '_';
+        buf[1] = i+'0';
+        buf[2] = '\0';
+        sym = intern_cstr(buf);
+        args = cons(new_arg(p, sym), args);
+        p->locals->car = cons(nsym(sym), p->locals->car);
+      }
+      a = new_args(p, args, 0, 0, 0, 0);
+    }
+  }
+  return a;
+}
+
 /* (:block arg body) */
 static node*
 new_block(parser_state *p, node *a, node *b)
 {
+  a = setup_numparams(p, a);
   return list4((node*)NODE_BLOCK, locals_node(p), a, b);
 }
 
@@ -822,19 +929,45 @@ new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b)
   return list4((node*)NODE_OP_ASGN, a, nsym(op), b);
 }
 
+static node*
+new_imaginary(parser_state *p, node *imaginary)
+{
+  return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Complex"), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1);
+}
+
+static node*
+new_rational(parser_state *p, node *rational)
+{
+  return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Rational"), list1(list1(rational)), 1);
+}
+
 /* (:int . i) */
 static node*
-new_int(parser_state *p, const char *s, int base)
+new_int(parser_state *p, const char *s, int base, int suffix)
 {
-  return list3((node*)NODE_INT, (node*)strdup(s), nint(base));
+  node* result = list3((node*)NODE_INT, (node*)strdup(s), nint(base));
+  if (suffix & NUM_SUFFIX_R) {
+    result = new_rational(p, result);
+  }
+  if (suffix & NUM_SUFFIX_I) {
+    result = new_imaginary(p, result);
+  }
+  return result;
 }
 
 #ifndef MRB_WITHOUT_FLOAT
 /* (:float . i) */
 static node*
-new_float(parser_state *p, const char *s)
+new_float(parser_state *p, const char *s, int suffix)
 {
-  return cons((node*)NODE_FLOAT, (node*)strdup(s));
+  node* result = cons((node*)NODE_FLOAT, (node*)strdup(s));
+  if (suffix & NUM_SUFFIX_R) {
+    result = new_rational(p, result);
+  }
+  if (suffix & NUM_SUFFIX_I) {
+    result = new_imaginary(p, result);
+  }
+  return result;
 }
 #endif
 
@@ -893,40 +1026,39 @@ concat_string(parser_state *p, node *a, node *b)
       }
     }
   }
-  else if (string_node_p(b)) {
-    /* a == NODE_DSTR && b == NODE_STR */
-
-    node *c;
+  else {
+    node *c; /* last node of a */
     for (c = a; c->cdr != NULL; c = c->cdr) ;
-    if (string_node_p(c->car)) {
-      /* a->[..., NODE_STR] && b == NODE_STR */
-      composite_string_node(p, c->car->cdr, b->cdr);
-      cons_free(b);
-      return a;
-    }
 
-    push(a, b);
-    return a;
-  }
-  else {
-    /* a == NODE_DSTR && b == NODE_DSTR */
+    if (string_node_p(b)) {
+      /* a == NODE_DSTR && b == NODE_STR */
+      if (string_node_p(c->car)) {
+        /* a->[..., NODE_STR] && b == NODE_STR */
+        composite_string_node(p, c->car->cdr, b->cdr);
+        cons_free(b);
+        return a;
+      }
 
-    node *c, *d;
-    for (c = a; c->cdr != NULL; c = c->cdr) ;
-    if (string_node_p(c->car) && string_node_p(b->cdr->car)) {
-      /* a->[..., NODE_STR] && b->[NODE_STR, ...] */
-      d = b->cdr;
-      cons_free(b);
-      composite_string_node(p, c->car->cdr, d->car->cdr);
-      cons_free(d->car);
-      c->cdr = d->cdr;
-      cons_free(d);
+      push(a, b);
       return a;
     }
     else {
-      c->cdr = b->cdr;
-      cons_free(b);
-      return a;
+      /* a == NODE_DSTR && b == NODE_DSTR */
+      if (string_node_p(c->car) && string_node_p(b->cdr->car)) {
+        /* a->[..., NODE_STR] && b->[NODE_STR, ...] */
+        node *d = b->cdr;
+        cons_free(b);
+        composite_string_node(p, c->car->cdr, d->car->cdr);
+        cons_free(d->car);
+        c->cdr = d->cdr;
+        cons_free(d);
+        return a;
+      }
+      else {
+        c->cdr = b->cdr;
+        cons_free(b);
+        return a;
+      }
     }
   }
 
@@ -1195,7 +1327,6 @@ heredoc_end(parser_state *p)
   p->parsing_heredoc = p->parsing_heredoc->cdr;
   if (p->parsing_heredoc == NULL) {
     p->lstate = EXPR_BEG;
-    p->cmd_start = TRUE;
     end_strterm(p);
     p->lex_strterm = p->lex_strterm_before_heredoc;
     p->lex_strterm_before_heredoc = NULL;
@@ -1211,7 +1342,8 @@ heredoc_end(parser_state *p)
 
 %}
 
-%pure-parser
+%define parse.error verbose
+%define api.pure
 %parse-param {parser_state *p}
 %lex-param {parser_state *p}
 
@@ -1280,6 +1412,7 @@ heredoc_end(parser_state *p)
 %token <nd>  tSTRING tSTRING_PART tSTRING_MID
 %token <nd>  tNTH_REF tBACK_REF
 %token <num> tREGEXP_END
+%token <num> tNUMPARAM
 
 %type <nd> singleton string string_fragment string_rep string_interp xstring regexp
 %type <nd> literal numeric cpath symbol
@@ -1412,11 +1545,13 @@ top_stmt        : stmt
                 | keyword_BEGIN
                     {
                       $<nd>$ = local_switch(p);
+                      nvars_block(p);
                     }
                   '{' top_compstmt '}'
                     {
                       yyerror(p, "BEGIN not supported");
                       local_resume(p, $<nd>2);
+                      nvars_unnest(p);
                       $$ = 0;
                     }
                 ;
@@ -1534,9 +1669,9 @@ command_asgn    : lhs '=' command_rhs
                     {
                       $$ = new_op_asgn(p, $1, $2, $3);
                     }
-                | primary_value '[' opt_call_args rbracket tOP_ASGN command_rhs
+                | primary_value '[' opt_call_args ']' tOP_ASGN command_rhs
                     {
-                      $$ = new_op_asgn(p, new_call(p, $1, intern("[]",2), $3, '.'), $5, $6);
+                      $$ = new_op_asgn(p, new_call(p, $1, intern_lit("[]"), $3, '.'), $5, $6);
                     }
                 | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
                     {
@@ -1614,6 +1749,7 @@ block_command   : block_call
 cmd_brace_block : tLBRACE_ARG
                     {
                       local_nest(p);
+                      nvars_nest(p);
                     }
                   opt_block_param
                   compstmt
@@ -1621,6 +1757,7 @@ cmd_brace_block : tLBRACE_ARG
                     {
                       $$ = new_block(p, $3, $4);
                       local_unnest(p);
+                      nvars_unnest(p);
                     }
                 ;
 
@@ -1763,9 +1900,9 @@ mlhs_node       : variable
                     {
                       assignable(p, $1);
                     }
-                | primary_value '[' opt_call_args rbracket
+                | primary_value '[' opt_call_args ']'
                     {
-                      $$ = new_call(p, $1, intern("[]",2), $3, '.');
+                      $$ = new_call(p, $1, intern_lit("[]"), $3, '.');
                     }
                 | primary_value call_op tIDENTIFIER
                     {
@@ -1802,9 +1939,9 @@ lhs             : variable
                     {
                       assignable(p, $1);
                     }
-                | primary_value '[' opt_call_args rbracket
+                | primary_value '[' opt_call_args ']'
                     {
-                      $$ = new_call(p, $1, intern("[]",2), $3, '.');
+                      $$ = new_call(p, $1, intern_lit("[]"), $3, '.');
                     }
                 | primary_value call_op tIDENTIFIER
                     {
@@ -1835,6 +1972,10 @@ lhs             : variable
                       backref_error(p, $1);
                       $$ = 0;
                     }
+                | tNUMPARAM
+                    {
+                      yyerror(p, "can't assign to numbered parameter");
+                    }
                 ;
 
 cname           : tIDENTIFIER
@@ -1888,36 +2029,36 @@ undef_list      : fsym
                     }
                 ;
 
-op              : '|'           { $$ = intern_c('|');   }
-                | '^'           { $$ = intern_c('^');   }
-                | '&'           { $$ = intern_c('&');   }
-                | tCMP          { $$ = intern("<=>",3); }
-                | tEQ           { $$ = intern("==",2);  }
-                | tEQQ          { $$ = intern("===",3); }
-                | tMATCH        { $$ = intern("=~",2);  }
-                | tNMATCH       { $$ = intern("!~",2);  }
-                | '>'           { $$ = intern_c('>');   }
-                | tGEQ          { $$ = intern(">=",2);  }
-                | '<'           { $$ = intern_c('<');   }
-                | tLEQ          { $$ = intern("<=",2);  }
-                | tNEQ          { $$ = intern("!=",2);  }
-                | tLSHFT        { $$ = intern("<<",2);  }
-                | tRSHFT        { $$ = intern(">>",2);  }
-                | '+'           { $$ = intern_c('+');   }
-                | '-'           { $$ = intern_c('-');   }
-                | '*'           { $$ = intern_c('*');   }
-                | tSTAR         { $$ = intern_c('*');   }
-                | '/'           { $$ = intern_c('/');   }
-                | '%'           { $$ = intern_c('%');   }
-                | tPOW          { $$ = intern("**",2);  }
-                | tDSTAR        { $$ = intern("**",2);  }
-                | '!'           { $$ = intern_c('!');   }
-                | '~'           { $$ = intern_c('~');   }
-                | tUPLUS        { $$ = intern("+@",2);  }
-                | tUMINUS       { $$ = intern("-@",2);  }
-                | tAREF         { $$ = intern("[]",2);  }
-                | tASET         { $$ = intern("[]=",3); }
-                | '`'           { $$ = intern_c('`');   }
+op              : '|'           { $$ = intern_lit("|");   }
+                | '^'           { $$ = intern_lit("^");   }
+                | '&'           { $$ = intern_lit("&");   }
+                | tCMP          { $$ = intern_lit("<=>"); }
+                | tEQ           { $$ = intern_lit("==");  }
+                | tEQQ          { $$ = intern_lit("==="); }
+                | tMATCH        { $$ = intern_lit("=~");  }
+                | tNMATCH       { $$ = intern_lit("!~");  }
+                | '>'           { $$ = intern_lit(">");   }
+                | tGEQ          { $$ = intern_lit(">=");  }
+                | '<'           { $$ = intern_lit("<");   }
+                | tLEQ          { $$ = intern_lit("<=");  }
+                | tNEQ          { $$ = intern_lit("!=");  }
+                | tLSHFT        { $$ = intern_lit("<<");  }
+                | tRSHFT        { $$ = intern_lit(">>");  }
+                | '+'           { $$ = intern_lit("+");   }
+                | '-'           { $$ = intern_lit("-");   }
+                | '*'           { $$ = intern_lit("*");   }
+                | tSTAR         { $$ = intern_lit("*");   }
+                | '/'           { $$ = intern_lit("/");   }
+                | '%'           { $$ = intern_lit("%");   }
+                | tPOW          { $$ = intern_lit("**");  }
+                | tDSTAR        { $$ = intern_lit("**");  }
+                | '!'           { $$ = intern_lit("!");   }
+                | '~'           { $$ = intern_lit("~");   }
+                | tUPLUS        { $$ = intern_lit("+@");  }
+                | tUMINUS       { $$ = intern_lit("-@");  }
+                | tAREF         { $$ = intern_lit("[]");  }
+                | tASET         { $$ = intern_lit("[]="); }
+                | '`'           { $$ = intern_lit("`");   }
                 ;
 
 reswords        : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
@@ -1942,9 +2083,9 @@ arg             : lhs '=' arg_rhs
                     {
                       $$ = new_op_asgn(p, $1, $2, $3);
                     }
-                | primary_value '[' opt_call_args rbracket tOP_ASGN arg_rhs
+                | primary_value '[' opt_call_args ']' tOP_ASGN arg_rhs
                     {
-                      $$ = new_op_asgn(p, new_call(p, $1, intern("[]",2), $3, '.'), $5, $6);
+                      $$ = new_op_asgn(p, new_call(p, $1, intern_lit("[]"), $3, '.'), $5, $6);
                     }
                 | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
                     {
@@ -2140,10 +2281,34 @@ arg_rhs         : arg %prec tOP_ASGN
                     }
                 ;
 
-paren_args      : '(' opt_call_args rparen
+paren_args      : '(' opt_call_args ')'
                     {
                       $$ = $2;
                     }
+                | '(' tDOT3 rparen
+                    {
+#if 1
+                      mrb_sym r = mrb_intern_lit(p->mrb, "*");
+                      mrb_sym b = mrb_intern_lit(p->mrb, "&");
+                      if (local_var_p(p, r)  && local_var_p(p, b)) {
+                        $$ = cons(list1(new_splat(p, new_lvar(p, r))),
+                                  new_block_arg(p, new_lvar(p, b)));
+                      }
+#else
+                      mrb_sym r = mrb_intern_lit(p->mrb, "*");
+                      mrb_sym k = mrb_intern_lit(p->mrb, "**");
+                      mrb_sym b = mrb_intern_lit(p->mrb, "&");
+                      if (local_var_p(p, r) && local_var_p(p, k) && local_var_p(p, b)) {
+                        $$ = cons(list2(new_splat(p, new_lvar(p, r)),
+                                        new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))),
+                                  new_block_arg(p, new_lvar(p, b)));
+                      }
+#endif
+                      else {
+                        yyerror(p, "unexpected argument forwarding ...");
+                        $$ = 0;
+                      }
+                    }
                 ;
 
 opt_paren_args  : none
@@ -2151,18 +2316,18 @@ opt_paren_args  : none
                 ;
 
 opt_call_args   : none
-                | call_args
-                | args ','
+                | call_args opt_terms
+                | args comma
                     {
                       $$ = cons($1,0);
                       NODE_LINENO($$, $1);
                     }
-                | args comma assocs ','
+                | args comma assocs comma
                     {
                       $$ = cons(push($1, new_kw_hash(p, $3)), 0);
                       NODE_LINENO($$, $1);
                     }
-                | assocs ','
+                | assocs comma
                     {
                       $$ = cons(list1(new_kw_hash(p, $1)), 0);
                       NODE_LINENO($$, $1);
@@ -2225,7 +2390,7 @@ opt_block_arg   : comma block_arg
                 ;
 
 comma           : ','
-                | ','  heredoc_bodies
+                | ','  opt_nl heredoc_bodies
                 ;
 
 args            : arg
@@ -2276,6 +2441,10 @@ primary         : literal
                 | heredoc
                 | var_ref
                 | backref
+                | tNUMPARAM
+                    {
+                      $$ = new_nvar(p, $1);
+                    }
                 | tFID
                     {
                       $$ = new_fcall(p, $1, 0);
@@ -2428,6 +2597,7 @@ primary         : literal
                       if (p->in_def || p->in_single)
                         yyerror(p, "class definition in method body");
                       $<nd>$ = local_switch(p);
+                      nvars_block(p);
                     }
                   bodystmt
                   keyword_end
@@ -2435,6 +2605,7 @@ primary         : literal
                       $$ = new_class(p, $2, $3, $5);
                       SET_LINENO($$, $1);
                       local_resume(p, $<nd>4);
+                      nvars_unnest(p);
                     }
                 | keyword_class
                   tLSHFT expr
@@ -2445,6 +2616,7 @@ primary         : literal
                   term
                     {
                       $<nd>$ = cons(local_switch(p), nint(p->in_single));
+                      nvars_block(p);
                       p->in_single = 0;
                     }
                   bodystmt
@@ -2453,6 +2625,7 @@ primary         : literal
                       $$ = new_sclass(p, $3, $7);
                       SET_LINENO($$, $1);
                       local_resume(p, $<nd>6->car);
+                      nvars_unnest(p);
                       p->in_def = $<num>4;
                       p->in_single = intn($<nd>6->cdr);
                     }
@@ -2462,6 +2635,7 @@ primary         : literal
                       if (p->in_def || p->in_single)
                         yyerror(p, "module definition in method body");
                       $<nd>$ = local_switch(p);
+                      nvars_block(p);
                     }
                   bodystmt
                   keyword_end
@@ -2469,6 +2643,7 @@ primary         : literal
                       $$ = new_module(p, $2, $4);
                       SET_LINENO($$, $1);
                       local_resume(p, $<nd>3);
+                      nvars_unnest(p);
                     }
                 | keyword_def fname
                     {
@@ -2478,6 +2653,7 @@ primary         : literal
                     {
                       p->in_def++;
                       $<nd>$ = local_switch(p);
+                      nvars_block(p);
                     }
                   f_arglist
                   bodystmt
@@ -2486,6 +2662,7 @@ primary         : literal
                       $$ = new_def(p, $2, $5, $6);
                       SET_LINENO($$, $1);
                       local_resume(p, $<nd>4);
+                      nvars_unnest(p);
                       p->in_def--;
                       p->cmdarg_stack = $<stack>3;
                     }
@@ -2500,6 +2677,7 @@ primary         : literal
                       p->in_single++;
                       p->lstate = EXPR_ENDFN; /* force for args */
                       $<nd>$ = local_switch(p);
+                      nvars_block(p);
                     }
                   f_arglist
                   bodystmt
@@ -2508,6 +2686,7 @@ primary         : literal
                       $$ = new_sdef(p, $2, $5, $7, $8);
                       SET_LINENO($$, $1);
                       local_resume(p, $<nd>6);
+                      nvars_unnest(p);
                       p->in_single--;
                       p->cmdarg_stack = $<stack>4;
                     }
@@ -2775,6 +2954,7 @@ lambda_body     : tLAMBEG compstmt '}'
 do_block        : keyword_do_block
                     {
                       local_nest(p);
+                      nvars_nest(p);
                     }
                   opt_block_param
                   bodystmt
@@ -2782,6 +2962,7 @@ do_block        : keyword_do_block
                     {
                       $$ = new_block(p,$3,$4);
                       local_unnest(p);
+                      nvars_unnest(p);
                     }
                 ;
 
@@ -2829,11 +3010,11 @@ method_call     : operation paren_args
                     }
                 | primary_value call_op paren_args
                     {
-                      $$ = new_call(p, $1, intern("call",4), $3, $2);
+                      $$ = new_call(p, $1, intern_lit("call"), $3, $2);
                     }
                 | primary_value tCOLON2 paren_args
                     {
-                      $$ = new_call(p, $1, intern("call",4), $3, tCOLON2);
+                      $$ = new_call(p, $1, intern_lit("call"), $3, tCOLON2);
                     }
                 | keyword_super paren_args
                     {
@@ -2843,15 +3024,16 @@ method_call     : operation paren_args
                     {
                       $$ = new_zsuper(p);
                     }
-                | primary_value '[' opt_call_args rbracket
+                | primary_value '[' opt_call_args ']'
                     {
-                      $$ = new_call(p, $1, intern("[]",2), $3, '.');
+                      $$ = new_call(p, $1, intern_lit("[]"), $3, '.');
                     }
                 ;
 
 brace_block     : '{'
                     {
                       local_nest(p);
+                      nvars_nest(p);
                       $<num>$ = p->lineno;
                     }
                   opt_block_param
@@ -2860,10 +3042,12 @@ brace_block     : '{'
                       $$ = new_block(p,$3,$4);
                       SET_LINENO($$, $<num>2);
                       local_unnest(p);
+                      nvars_unnest(p);
                     }
                 | keyword_do
                     {
                       local_nest(p);
+                      nvars_nest(p);
                       $<num>$ = p->lineno;
                     }
                   opt_block_param
@@ -2872,6 +3056,7 @@ brace_block     : '{'
                       $$ = new_block(p,$3,$4);
                       SET_LINENO($$, $<num>2);
                       local_unnest(p);
+                      nvars_unnest(p);
                     }
                 ;
 
@@ -3138,6 +3323,10 @@ var_lhs         : variable
                     {
                       assignable(p, $1);
                     }
+                | tNUMPARAM
+                    {
+                      yyerror(p, "can't assign to numbered parameter");
+                    }
                 ;
 
 var_ref         : variable
@@ -3162,7 +3351,7 @@ var_ref         : variable
                     }
                 | keyword__FILE__
                     {
-                      const char *fn = mrb_sym2name_len(p->mrb, p->filename_sym, NULL);
+                      const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
                       if (!fn) {
                         fn = "(null)";
                       }
@@ -3172,8 +3361,8 @@ var_ref         : variable
                     {
                       char buf[16];
 
-                      snprintf(buf, sizeof(buf), "%d", p->lineno);
-                      $$ = new_int(p, buf, 10);
+                      dump_int(p->lineno, buf);
+                      $$ = new_int(p, buf, 10, 0);
                     }
                 | keyword__ENCODING__
                     {
@@ -3216,6 +3405,24 @@ f_arglist       : '(' f_args rparen
                       p->lstate = EXPR_BEG;
                       p->cmd_start = TRUE;
                     }
+                | '(' tDOT3 rparen
+                    {
+#if 1
+                      /* til real keyword args implemented */
+                      mrb_sym r = mrb_intern_lit(p->mrb, "*");
+                      mrb_sym b = mrb_intern_lit(p->mrb, "&");
+                      local_add_f(p, r);
+                      $$ = new_args(p, 0, 0, r, 0,
+                                    new_args_tail(p, 0, 0, b));
+#else
+                      mrb_sym r = mrb_intern_lit(p->mrb, "*");
+                      mrb_sym k = mrb_intern_lit(p->mrb, "**");
+                      mrb_sym b = mrb_intern_lit(p->mrb, "&");
+                      local_add_f(p, r); local_add_f(p, k);
+                      $$ = new_args(p, 0, 0, r, 0,
+                                    new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b));
+#endif
+                    }
                 | f_args term
                     {
                       $$ = $1;
@@ -3223,26 +3430,33 @@ f_arglist       : '(' f_args rparen
                 ;
 
 f_label         : tIDENTIFIER tLABEL_TAG
+                    {
+                      local_nest(p);
+                    }
                 ;
 
 f_kw            : f_label arg
                     {
                       void_expr_error(p, $2);
-                      $$ = new_kw_arg(p, $1, $2);
+                      $$ = new_kw_arg(p, $1, cons($2, locals_node(p)));
+                      local_unnest(p);
                     }
                 | f_label
                     {
                       $$ = new_kw_arg(p, $1, 0);
+                      local_unnest(p);
                     }
                 ;
 
 f_block_kw      : f_label primary_value
                     {
-                      $$ = new_kw_arg(p, $1, $2);
+                      $$ = new_kw_arg(p, $1, cons($2, locals_node(p)));
+                      local_unnest(p);
                     }
                 | f_label
                     {
                       $$ = new_kw_arg(p, $1, 0);
+                      local_unnest(p);
                     }
                 ;
 
@@ -3272,11 +3486,11 @@ kwrest_mark     : tPOW
 
 f_kwrest        : kwrest_mark tIDENTIFIER
                     {
-                      $$ = cons((node*)NODE_KW_REST_ARGS, nsym($2));
+                      $$ = new_kw_rest_args(p, nsym($2));
                     }
                 | kwrest_mark
                     {
-                      $$ = cons((node*)NODE_KW_REST_ARGS, 0);
+                      $$ = new_kw_rest_args(p, 0);
                     }
                 ;
 
@@ -3391,6 +3605,11 @@ f_bad_arg       : tCONSTANT
                       yyerror(p, "formal argument cannot be a class variable");
                       $$ = 0;
                     }
+                | tNUMPARAM
+                    {
+                      yyerror(p, "formal argument cannot be a numbered parameter");
+                      $$ = 0;
+                    }
                 ;
 
 f_norm_arg      : f_bad_arg
@@ -3433,6 +3652,7 @@ f_arg           : f_arg_item
 f_opt_asgn      : tIDENTIFIER '='
                     {
                       local_add_f(p, $1);
+                      local_nest(p);
                       $$ = $1;
                     }
                 ;
@@ -3440,14 +3660,16 @@ f_opt_asgn      : tIDENTIFIER '='
 f_opt           : f_opt_asgn arg
                     {
                       void_expr_error(p, $2);
-                      $$ = cons(nsym($1), $2);
+                      $$ = cons(nsym($1), cons($2, locals_node(p)));
+                      local_unnest(p);
                     }
                 ;
 
 f_block_opt     : f_opt_asgn primary_value
                     {
                       void_expr_error(p, $2);
-                      $$ = cons(nsym($1), $2);
+                      $$ = cons(nsym($1), cons($2, locals_node(p)));
+                      local_unnest(p);
                     }
                 ;
 
@@ -3549,24 +3771,28 @@ assocs          : assoc
                       $$ = list1($1);
                       NODE_LINENO($$, $1);
                     }
-                | assocs ',' assoc
+                | assocs comma assoc
                     {
                       $$ = push($1, $3);
                     }
                 ;
 
+label_tag       : tLABEL_TAG
+                | tLABEL_TAG heredoc_bodies
+                ;
+
 assoc           : arg tASSOC arg
                     {
                       void_expr_error(p, $1);
                       void_expr_error(p, $3);
                       $$ = cons($1, $3);
                     }
-                | tIDENTIFIER tLABEL_TAG arg
+                | tIDENTIFIER label_tag arg
                     {
                       void_expr_error(p, $3);
                       $$ = cons(new_sym(p, $1), $3);
                     }
-                | string_fragment tLABEL_TAG arg
+                | string_fragment label_tag arg
                     {
                       void_expr_error(p, $3);
                       if ($1->car == (node*)NODE_DSTR) {
@@ -3579,7 +3805,7 @@ assoc           : arg tASSOC arg
                 | tDSTAR arg
                     {
                       void_expr_error(p, $2);
-                      $$ = cons(cons((node*)NODE_KW_REST_ARGS, 0), $2);
+                      $$ = cons(new_kw_rest_args(p, 0), $2);
                     }
                 ;
 
@@ -3628,14 +3854,11 @@ opt_nl          : /* none */
                 | nl
                 ;
 
-rparen          : opt_nl ')'
-                ;
-
-rbracket        : opt_nl ']'
+rparen          : opt_terms ')'
                 ;
 
 trailer         : /* none */
-                | nl
+                | terms
                 | comma
                 ;
 
@@ -3646,7 +3869,7 @@ term            : ';' {yyerrok;}
 
 nl              : '\n'
                     {
-                      p->lineno++;
+                      p->lineno += $<num>1;
                       p->column = 0;
                     }
                 ;
@@ -3672,7 +3895,7 @@ yyerror(parser_state *p, const char *s)
   if (! p->capture_errors) {
 #ifndef MRB_DISABLE_STDIO
     if (p->filename_sym) {
-      const char *filename = mrb_sym2name_len(p->mrb, p->filename_sym, NULL);
+      const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
       fprintf(stderr, "%s:%d:%d: %s\n", filename, p->lineno, p->column, s);
     }
     else {
@@ -3692,11 +3915,13 @@ yyerror(parser_state *p, const char *s)
 }
 
 static void
-yyerror_i(parser_state *p, const char *fmt, int i)
+yyerror_c(parser_state *p, const char *msg, char c)
 {
   char buf[256];
 
-  snprintf(buf, sizeof(buf), fmt, i);
+  strncpy(buf, msg, sizeof(buf) - 2);
+  buf[sizeof(buf) - 2] = '\0';
+  strncat(buf, &c, 1);
   yyerror(p, buf);
 }
 
@@ -3709,7 +3934,7 @@ yywarn(parser_state *p, const char *s)
   if (! p->capture_errors) {
 #ifndef MRB_DISABLE_STDIO
     if (p->filename_sym) {
-      const char *filename = mrb_sym2name_len(p->mrb, p->filename_sym, NULL);
+      const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
       fprintf(stderr, "%s:%d:%d: warning: %s\n", filename, p->lineno, p->column, s);
     }
     else {
@@ -3735,11 +3960,14 @@ yywarning(parser_state *p, const char *s)
 }
 
 static void
-yywarning_s(parser_state *p, const char *fmt, const char *s)
+yywarning_s(parser_state *p, const char *msg, const char *s)
 {
   char buf[256];
 
-  snprintf(buf, sizeof(buf), fmt, s);
+  strncpy(buf, msg, sizeof(buf) - 1);
+  buf[sizeof(buf) - 1] = '\0';
+  strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1);
+  strncat(buf, s, sizeof(buf) - strlen(buf) - 1);
   yywarning(p, buf);
 }
 
@@ -3751,13 +3979,13 @@ backref_error(parser_state *p, node *n)
   c = intn(n->car);
 
   if (c == NODE_NTH_REF) {
-    yyerror_i(p, "can't set variable $%" MRB_PRId, intn(n->cdr));
+    yyerror_c(p, "can't set variable $", (char)intn(n->cdr)+'0');
   }
   else if (c == NODE_BACK_REF) {
-    yyerror_i(p, "can't set variable $%c", intn(n->cdr));
+    yyerror_c(p, "can't set variable $", (char)intn(n->cdr));
   }
   else {
-    mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %S", mrb_fixnum_value(c));
+    mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %d", c);
   }
 }
 
@@ -3801,6 +4029,27 @@ static mrb_bool peeks(parser_state *p, const char *s);
 static mrb_bool skips(parser_state *p, const char *s);
 
 static inline int
+nextc0(parser_state *p)
+{
+  int c;
+#ifndef MRB_DISABLE_STDIO
+  if (p->f) {
+    if (feof(p->f)) return -1;
+    c = fgetc(p->f);
+    if (c == EOF) return -1;
+  }
+  else
+#endif
+    if (!p->s || p->s >= p->send) {
+      return -1;
+    }
+    else {
+      c = (unsigned char)*p->s++;
+    }
+  return c;
+}
+
+static inline int
 nextc(parser_state *p)
 {
   int c;
@@ -3814,24 +4063,19 @@ nextc(parser_state *p)
     cons_free(tmp);
   }
   else {
-#ifndef MRB_DISABLE_STDIO
-    if (p->f) {
-      if (feof(p->f)) goto eof;
-      c = fgetc(p->f);
-      if (c == EOF) goto eof;
-    }
-    else
-#endif
-      if (!p->s || p->s >= p->send) {
-        goto eof;
-      }
-      else {
-        c = (unsigned char)*p->s++;
-      }
+    c = nextc0(p);
+    if (c < 0) goto eof;
   }
   if (c >= 0) {
     p->column++;
   }
+  if (c == '\r') {
+    const int lf = nextc0(p);
+    if (lf == '\n') {
+      return '\n';
+    }
+    if (lf > 0) pushback(p, lf);
+  }
   return c;
 
   eof:
@@ -4288,18 +4532,22 @@ parse_string(parser_state *p)
           }
         }
         if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) {
-          if (c < 0) {
-            p->parsing_heredoc = NULL;
-          }
-          else {
-            return tHEREDOC_END;
-          }
+          return tHEREDOC_END;
         }
       }
       if (c < 0) {
         char buf[256];
-        snprintf(buf, sizeof(buf), "can't find heredoc delimiter \"%s\" anywhere before EOF", hinf->term);
-        yyerror(p, buf);
+        const char s1[] = "can't find heredoc delimiter \"";
+        const char s2[] = "\" anywhere before EOF";
+
+        if (sizeof(s1)+sizeof(s2)+strlen(hinf->term)+1 >= sizeof(buf)) {
+          yyerror(p, "can't find heredoc delimiter anywhere before EOF");
+        } else {
+          strcpy(buf, s1);
+          strcat(buf, hinf->term);
+          strcat(buf, s2);
+          yyerror(p, buf);
+        }
         return 0;
       }
       pylval.nd = new_str(p, tok(p), toklen(p));
@@ -4443,15 +4691,21 @@ parse_string(parser_state *p)
       case 'm': f |= 4; break;
       case 'u': f |= 16; break;
       case 'n': f |= 32; break;
+      case 'o': break;
       default: tokadd(p, re_opt); break;
       }
     }
     pushback(p, re_opt);
     if (toklen(p)) {
       char msg[128];
+
+      strcpy(msg, "unknown regexp option");
       tokfix(p);
-      snprintf(msg, sizeof(msg), "unknown regexp option%s - %s",
-          toklen(p) > 1 ? "s" : "", tok(p));
+      if (toklen(p) > 1) {
+        strcat(msg, "s");
+      }
+      strcat(msg, " - ");
+      strncat(msg, tok(p), sizeof(msg) - strlen(msg) - 1);
       yyerror(p, msg);
     }
     if (f != 0) {
@@ -4482,6 +4736,44 @@ parse_string(parser_state *p)
   return tSTRING;
 }
 
+static int
+number_literal_suffix(parser_state *p)
+{
+  int c, result = 0;
+  node *list = 0;
+  int column = p->column;
+  int mask = NUM_SUFFIX_R|NUM_SUFFIX_I;
+
+  while ((c = nextc(p)) != -1) {
+    list = push(list, (node*)(intptr_t)c);
+
+    if ((mask & NUM_SUFFIX_I) && c == 'i') {
+      result |= (mask & NUM_SUFFIX_I);
+      mask &= ~NUM_SUFFIX_I;
+      /* r after i, rational of complex is disallowed */
+      mask &= ~NUM_SUFFIX_R;
+      continue;
+    }
+    if ((mask & NUM_SUFFIX_R) && c == 'r') {
+      result |= (mask & NUM_SUFFIX_R);
+      mask &= ~NUM_SUFFIX_R;
+      continue;
+    }
+    if (!ISASCII(c) || ISALPHA(c) || c == '_') {
+      p->column = column;
+      if (p->pb) {
+        p->pb = append((node*)list, p->pb);
+      }
+      else {
+        p->pb = list;
+      }
+      return 0;
+    }
+    pushback(p, c);
+    break;
+  }
+  return result;
+}
 
 static int
 heredoc_identifier(parser_state *p)
@@ -4565,6 +4857,7 @@ static int
 parser_yylex(parser_state *p)
 {
   int32_t c;
+  int nlines = 1;
   int space_seen = 0;
   int cmd_state;
   enum mrb_lex_state_enum last_state;
@@ -4602,57 +4895,73 @@ parser_yylex(parser_state *p)
     /* fall through */
   case -2:      /* end of a file */
   case '\n':
-    maybe_heredoc:
+  maybe_heredoc:
     heredoc_treat_nextline(p);
-  switch (p->lstate) {
-  case EXPR_BEG:
-  case EXPR_FNAME:
-  case EXPR_DOT:
-  case EXPR_CLASS:
-  case EXPR_VALUE:
-    p->lineno++;
     p->column = 0;
-    if (p->parsing_heredoc != NULL) {
-      if (p->lex_strterm) {
-        return parse_string(p);
+    switch (p->lstate) {
+    case EXPR_BEG:
+    case EXPR_FNAME:
+    case EXPR_DOT:
+    case EXPR_CLASS:
+    case EXPR_VALUE:
+      p->lineno++;
+      if (p->parsing_heredoc != NULL) {
+        if (p->lex_strterm) {
+          return parse_string(p);
+        }
       }
-    }
-    goto retry;
-  default:
-    break;
-  }
-  if (p->parsing_heredoc != NULL) {
-    return '\n';
-  }
-  while ((c = nextc(p))) {
-    switch (c) {
-    case ' ': case '\t': case '\f': case '\r':
-    case '\13': /* '\v' */
-      space_seen = 1;
+      goto retry;
+    default:
       break;
-    case '.':
-      if ((c = nextc(p)) != '.') {
+    }
+    if (p->parsing_heredoc != NULL) {
+      pylval.num = nlines;
+      return '\n';
+    }
+    while ((c = nextc(p))) {
+      switch (c) {
+      case ' ': case '\t': case '\f': case '\r':
+      case '\13': /* '\v' */
+        space_seen = 1;
+        break;
+      case '#': /* comment as a whitespace */
+        skip(p, '\n');
+        nlines++;
+        break;
+      case '.':
+        if (!peek(p, '.')) {
+          pushback(p, '.');
+          p->lineno+=nlines; nlines=1;
+          goto retry;
+        }
         pushback(p, c);
-        pushback(p, '.');
-        goto retry;
+        goto normal_newline;
+      case '&':
+        if (peek(p, '.')) {
+          pushback(p, '&');
+          p->lineno+=nlines; nlines=1;
+          goto retry;
+        }
+        pushback(p, c);
+        goto normal_newline;
+      case -1:                  /* EOF */
+      case -2:                  /* end of a file */
+        goto normal_newline;
+      default:
+        pushback(p, c);
+        goto normal_newline;
       }
-    case -1:                  /* EOF */
-    case -2:                  /* end of a file */
-      goto normal_newline;
-    default:
-      pushback(p, c);
-      goto normal_newline;
     }
-  }
   normal_newline:
-  p->cmd_start = TRUE;
-  p->lstate = EXPR_BEG;
-  return '\n';
+    p->cmd_start = TRUE;
+    p->lstate = EXPR_BEG;
+    pylval.num = nlines;
+    return '\n';
 
   case '*':
     if ((c = nextc(p)) == '*') {
       if ((c = nextc(p)) == '=') {
-        pylval.id = intern("**",2);
+        pylval.id = intern_lit("**");
         p->lstate = EXPR_BEG;
         return tOP_ASGN;
       }
@@ -4670,7 +4979,7 @@ parser_yylex(parser_state *p)
     }
     else {
       if (c == '=') {
-        pylval.id = intern_c('*');
+        pylval.id = intern_lit("*");
         p->lstate = EXPR_BEG;
         return tOP_ASGN;
       }
@@ -4729,7 +5038,7 @@ parser_yylex(parser_state *p)
             c = nextc(p);
           } while (!(c < 0 || ISSPACE(c)));
           if (c != '\n') skip(p, '\n');
-          p->lineno++;
+          p->lineno+=nlines; nlines=1;
           p->column = 0;
           goto retry;
         }
@@ -4786,7 +5095,7 @@ parser_yylex(parser_state *p)
     }
     if (c == '<') {
       if ((c = nextc(p)) == '=') {
-        pylval.id = intern("<<",2);
+        pylval.id = intern_lit("<<");
         p->lstate = EXPR_BEG;
         return tOP_ASGN;
       }
@@ -4808,7 +5117,7 @@ parser_yylex(parser_state *p)
     }
     if (c == '>') {
       if ((c = nextc(p)) == '=') {
-        pylval.id = intern(">>",2);
+        pylval.id = intern_lit(">>");
         p->lstate = EXPR_BEG;
         return tOP_ASGN;
       }
@@ -4879,7 +5188,10 @@ parser_yylex(parser_state *p)
         }
         if (c2) {
           char buf[256];
-          snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2);
+          char cc[] = { (char)c2, '\0' };
+
+          strcpy(buf, "invalid character syntax; use ?\\");
+          strncat(buf, cc, 2);
           yyerror(p, buf);
         }
       }
@@ -4913,7 +5225,7 @@ parser_yylex(parser_state *p)
     if ((c = nextc(p)) == '&') {
       p->lstate = EXPR_BEG;
       if ((c = nextc(p)) == '=') {
-        pylval.id = intern("&&",2);
+        pylval.id = intern_lit("&&");
         p->lstate = EXPR_BEG;
         return tOP_ASGN;
       }
@@ -4925,7 +5237,7 @@ parser_yylex(parser_state *p)
       return tANDDOT;
     }
     else if (c == '=') {
-      pylval.id = intern_c('&');
+      pylval.id = intern_lit("&");
       p->lstate = EXPR_BEG;
       return tOP_ASGN;
     }
@@ -4952,7 +5264,7 @@ parser_yylex(parser_state *p)
     if ((c = nextc(p)) == '|') {
       p->lstate = EXPR_BEG;
       if ((c = nextc(p)) == '=') {
-        pylval.id = intern("||",2);
+        pylval.id = intern_lit("||");
         p->lstate = EXPR_BEG;
         return tOP_ASGN;
       }
@@ -4960,7 +5272,7 @@ parser_yylex(parser_state *p)
       return tOROP;
     }
     if (c == '=') {
-      pylval.id = intern_c('|');
+      pylval.id = intern_lit("|");
       p->lstate = EXPR_BEG;
       return tOP_ASGN;
     }
@@ -4984,7 +5296,7 @@ parser_yylex(parser_state *p)
       return '+';
     }
     if (c == '=') {
-      pylval.id = intern_c('+');
+      pylval.id = intern_lit("+");
       p->lstate = EXPR_BEG;
       return tOP_ASGN;
     }
@@ -5012,7 +5324,7 @@ parser_yylex(parser_state *p)
       return '-';
     }
     if (c == '=') {
-      pylval.id = intern_c('-');
+      pylval.id = intern_lit("-");
       p->lstate = EXPR_BEG;
       return tOP_ASGN;
     }
@@ -5053,6 +5365,7 @@ parser_yylex(parser_state *p)
   case '5': case '6': case '7': case '8': case '9':
   {
     int is_float, seen_point, seen_e, nondigit;
+    int suffix = 0;
 
     is_float = seen_point = seen_e = nondigit = 0;
     p->lstate = EXPR_ENDARG;
@@ -5086,7 +5399,8 @@ parser_yylex(parser_state *p)
           no_digits();
         }
         else if (nondigit) goto trailing_uc;
-        pylval.nd = new_int(p, tok(p), 16);
+        suffix = number_literal_suffix(p);
+        pylval.nd = new_int(p, tok(p), 16, suffix);
         return tINTEGER;
       }
       if (c == 'b' || c == 'B') {
@@ -5110,7 +5424,8 @@ parser_yylex(parser_state *p)
           no_digits();
         }
         else if (nondigit) goto trailing_uc;
-        pylval.nd = new_int(p, tok(p), 2);
+        suffix = number_literal_suffix(p);
+        pylval.nd = new_int(p, tok(p), 2, suffix);
         return tINTEGER;
       }
       if (c == 'd' || c == 'D') {
@@ -5134,7 +5449,8 @@ parser_yylex(parser_state *p)
           no_digits();
         }
         else if (nondigit) goto trailing_uc;
-        pylval.nd = new_int(p, tok(p), 10);
+        suffix = number_literal_suffix(p);
+        pylval.nd = new_int(p, tok(p), 10, suffix);
         return tINTEGER;
       }
       if (c == '_') {
@@ -5167,7 +5483,8 @@ parser_yylex(parser_state *p)
           pushback(p, c);
           tokfix(p);
           if (nondigit) goto trailing_uc;
-          pylval.nd = new_int(p, tok(p), 8);
+          suffix = number_literal_suffix(p);
+          pylval.nd = new_int(p, tok(p), 8, suffix);
           return tINTEGER;
         }
         if (nondigit) {
@@ -5184,7 +5501,8 @@ parser_yylex(parser_state *p)
       }
       else {
         pushback(p, c);
-        pylval.nd = new_int(p, "0", 10);
+        suffix = number_literal_suffix(p);
+        pylval.nd = new_int(p, "0", 10, suffix);
         return tINTEGER;
       }
     }
@@ -5252,13 +5570,13 @@ parser_yylex(parser_state *p)
     pushback(p, c);
     if (nondigit) {
       trailing_uc:
-      yyerror_i(p, "trailing '%c' in number", nondigit);
+      yyerror_c(p, "trailing non digit in number: ", (char)nondigit);
     }
     tokfix(p);
     if (is_float) {
 #ifdef MRB_WITHOUT_FLOAT
-      yywarning(p, "floating point numbers are not supported");
-      pylval.nd = new_int(p, "0", 10);
+      yywarning_s(p, "floating point numbers are not supported", tok(p));
+      pylval.nd = new_int(p, "0", 10, 0);
       return tINTEGER;
 #else
       double d;
@@ -5267,17 +5585,19 @@ parser_yylex(parser_state *p)
       errno = 0;
       d = mrb_float_read(tok(p), &endp);
       if (d == 0 && endp == tok(p)) {
-        yywarning_s(p, "corrupted float value %s", tok(p));
+        yywarning_s(p, "corrupted float value", tok(p));
       }
       else if (errno == ERANGE) {
-        yywarning_s(p, "float %s out of range", tok(p));
+        yywarning_s(p, "float out of range", tok(p));
         errno = 0;
       }
-      pylval.nd = new_float(p, tok(p));
+      suffix = number_literal_suffix(p);
+      pylval.nd = new_float(p, tok(p), suffix);
       return tFLOAT;
 #endif
     }
-    pylval.nd = new_int(p, tok(p), 10);
+    suffix = number_literal_suffix(p);
+    pylval.nd = new_int(p, tok(p), 10, suffix);
     return tINTEGER;
   }
 
@@ -5324,7 +5644,7 @@ parser_yylex(parser_state *p)
       return tREGEXP_BEG;
     }
     if ((c = nextc(p)) == '=') {
-      pylval.id = intern_c('/');
+      pylval.id = intern_lit("/");
       p->lstate = EXPR_BEG;
       return tOP_ASGN;
     }
@@ -5343,7 +5663,7 @@ parser_yylex(parser_state *p)
 
   case '^':
     if ((c = nextc(p)) == '=') {
-      pylval.id = intern_c('^');
+      pylval.id = intern_lit("^");
       p->lstate = EXPR_BEG;
       return tOP_ASGN;
     }
@@ -5440,7 +5760,7 @@ parser_yylex(parser_state *p)
   case '\\':
     c = nextc(p);
     if (c == '\n') {
-      p->lineno++;
+      p->lineno+=nlines; nlines=1;
       p->column = 0;
       space_seen = 1;
       goto retry; /* skip \\n */
@@ -5520,7 +5840,7 @@ parser_yylex(parser_state *p)
       }
     }
     if ((c = nextc(p)) == '=') {
-      pylval.id = intern_c('%');
+      pylval.id = intern_lit("%");
       p->lstate = EXPR_BEG;
       return tOP_ASGN;
     }
@@ -5574,7 +5894,7 @@ parser_yylex(parser_state *p)
       tokadd(p, '$');
       tokadd(p, c);
       tokfix(p);
-      pylval.id = intern_cstr(tok(p));
+      pylval.id = intern(tok(p), toklen(p));
       return tGVAR;
 
     case '-':
@@ -5584,7 +5904,7 @@ parser_yylex(parser_state *p)
       pushback(p, c);
       gvar:
       tokfix(p);
-      pylval.id = intern_cstr(tok(p));
+      pylval.id = intern(tok(p), toklen(p));
       return tGVAR;
 
     case '&':     /* $&: last match */
@@ -5612,7 +5932,7 @@ parser_yylex(parser_state *p)
       {
         unsigned long n = strtoul(tok(p), NULL, 10);
         if (n > INT_MAX) {
-          yyerror_i(p, "capture group index must be <= %d", INT_MAX);
+          yyerror(p, "capture group index must be <= " MRB_STRINGIZE(INT_MAX));
           return 0;
         }
         pylval.nd = new_nth_ref(p, (int)n);
@@ -5649,10 +5969,10 @@ parser_yylex(parser_state *p)
       }
       else if (ISDIGIT(c)) {
         if (p->tidx == 1) {
-          yyerror_i(p, "'@%c' is not allowed as an instance variable name", c);
+          yyerror_c(p, "wrong instance variable name: @", c);
         }
         else {
-          yyerror_i(p, "'@@%c' is not allowed as a class variable name", c);
+          yyerror_c(p, "wrong class variable name: @@", c);
         }
         return 0;
       }
@@ -5668,7 +5988,15 @@ parser_yylex(parser_state *p)
 
     default:
       if (!identchar(c)) {
-        yyerror_i(p,  "Invalid char '\\x%02X' in expression", c);
+        char buf[36];
+        const char s[] = "Invalid char in expression: 0x";
+        const char hexdigits[] = "0123456789ABCDEF";
+
+        strcpy(buf, s);
+        buf[sizeof(s)-1] = hexdigits[(c & 0xf0) >> 4];
+        buf[sizeof(s)]   = hexdigits[(c & 0x0f)];
+        buf[sizeof(s)+1] = 0;
+        yyerror(p, buf);
         goto retry;
       }
 
@@ -5714,6 +6042,39 @@ parser_yylex(parser_state *p)
         result = tIVAR;
       break;
 
+    case '_':
+      if (toklen(p) == 2 && ISDIGIT(tok(p)[1]) && p->nvars) {
+        int n = tok(p)[1] - '0';
+        int nvar;
+
+        if (n > 0) {
+          node *nvars = p->nvars->cdr;
+
+          while (nvars) {
+            nvar = intn(nvars->car);
+            if (nvar == -2) break; /* top of the scope */
+            if (nvar > 0) {
+              yywarning(p, "numbered parameter used in outer block");
+              break;
+            }
+            nvars->car = nint(-1);
+            nvars = nvars->cdr;
+          }
+          nvar = intn(p->nvars->car);
+          if (nvar == -1) {
+            yywarning(p, "numbered parameter used in inner block");
+          }
+          if (nvar >= -1) {
+            pylval.num = n;
+            p->lstate = EXPR_END;
+            return tNUMPARAM;
+          }
+          else {
+            yywarning(p, "identifier for numbered parameter; consider another name");
+          }
+        }
+      }
+      /* fall through */
     default:
       if (toklast(p) == '!' || toklast(p) == '?') {
         result = tFID;
@@ -5729,6 +6090,15 @@ parser_yylex(parser_state *p)
           else {
             pushback(p, c);
           }
+          if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
+              (!peek(p, '=') || (peek_n(p, '>', 1)))) {
+            result = tIDENTIFIER;
+            tokadd(p, c);
+            tokfix(p);
+          }
+          else {
+            pushback(p, c);
+          }
         }
         if (result == 0 && ISUPPER(tok(p)[0])) {
           result = tCONSTANT;
@@ -5742,7 +6112,7 @@ parser_yylex(parser_state *p)
         if (IS_LABEL_SUFFIX(0)) {
           p->lstate = EXPR_END;
           tokfix(p);
-          pylval.id = intern_cstr(tok(p));
+          pylval.id = intern(tok(p), toklen(p));
           return tIDENTIFIER;
         }
       }
@@ -5801,7 +6171,7 @@ parser_yylex(parser_state *p)
       }
     }
     {
-      mrb_sym ident = intern_cstr(tok(p));
+      mrb_sym ident = intern(tok(p), toklen(p));
 
       pylval.id = ident;
       if (last_state != EXPR_DOT && ISLOWER(tok(p)[0]) && local_var_p(p, ident)) {
@@ -5835,7 +6205,7 @@ parser_init_cxt(parser_state *p, mrbc_context *cxt)
   }
   p->capture_errors = cxt->capture_errors;
   p->no_optimize = cxt->no_optimize;
-  p->on_eval = cxt->on_eval;
+  p->upper = cxt->upper;
   if (cxt->partial_hook) {
     p->cxt = cxt;
   }
@@ -6097,11 +6467,12 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
     if (c) c->parser_nerr = p->nerr;
     if (p->capture_errors) {
       char buf[256];
-      int n;
 
-      n = snprintf(buf, sizeof(buf), "line %d: %s\n",
-          p->error_buffer[0].lineno, p->error_buffer[0].message);
-      mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
+      strcpy(buf, "line ");
+      dump_int(p->error_buffer[0].lineno, buf+5);
+      strcat(buf, ": ");
+      strncat(buf, p->error_buffer[0].message, sizeof(buf) - strlen(buf) - 1);
+      mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, strlen(buf)));
       mrb_parser_free(p);
       return mrb_undef_value();
     }
@@ -6219,7 +6590,7 @@ dump_args(mrb_state *mrb, node *n, int offset)
 
       while (n2) {
         dump_prefix(n2, offset+2);
-        printf("%s=\n", mrb_sym2name(mrb, sym(n2->car->car)));
+        printf("%s=\n", mrb_sym_name(mrb, sym(n2->car->car)));
         mrb_parser_dump(mrb, n2->car->cdr, offset+3);
         n2 = n2->cdr;
       }
@@ -6228,7 +6599,7 @@ dump_args(mrb_state *mrb, node *n, int offset)
   n = n->cdr;
   if (n->car) {
     dump_prefix(n, offset+1);
-    printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+    printf("rest=*%s\n", mrb_sym_name(mrb, sym(n->car)));
   }
   n = n->cdr;
   if (n->car) {
@@ -6244,6 +6615,28 @@ dump_args(mrb_state *mrb, node *n, int offset)
   }
 }
 
+/*
+ * This function restores the GC arena on return.
+ * For this reason, if a process that further generates an object is
+ * performed at the caller, the string pointer returned as the return
+ * value may become invalid.
+ */
+static const char*
+str_dump(mrb_state *mrb, const char *str, int len)
+{
+  int ai = mrb_gc_arena_save(mrb);
+  mrb_value s;
+# if INT_MAX > MRB_INT_MAX / 4
+  /* check maximum length with "\xNN" charactor */
+  if (len > MRB_INT_MAX / 4) {
+    len = MRB_INT_MAX / 4;
+  }
+# endif
+  s = mrb_str_new(mrb, str, (mrb_int)len);
+  s = mrb_str_dump(mrb, s);
+  mrb_gc_arena_restore(mrb, ai);
+  return RSTRING_PTR(s);
+}
 #endif
 
 void
@@ -6447,7 +6840,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
         while (n2) {
           if (n2->car) {
             if (!first_lval) printf(", ");
-            printf("%s", mrb_sym2name(mrb, sym(n2->car)));
+            printf("%s", mrb_sym_name(mrb, sym(n2->car)));
             first_lval = FALSE;
           }
           n2 = n2->cdr;
@@ -6475,7 +6868,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     mrb_parser_dump(mrb, tree->car, offset+1);
     dump_prefix(tree, offset+1);
     printf("method='%s' (%d)\n",
-        mrb_sym2name(mrb, sym(tree->cdr->car)),
+        mrb_sym_dump(mrb, sym(tree->cdr->car)),
         intn(tree->cdr->car));
     tree = tree->cdr->cdr->car;
     if (tree) {
@@ -6506,11 +6899,11 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     printf("NODE_COLON2:\n");
     mrb_parser_dump(mrb, tree->car, offset+1);
     dump_prefix(tree, offset+1);
-    printf("::%s\n", mrb_sym2name(mrb, sym(tree->cdr)));
+    printf("::%s\n", mrb_sym_name(mrb, sym(tree->cdr)));
     break;
 
   case NODE_COLON3:
-    printf("NODE_COLON3: ::%s\n", mrb_sym2name(mrb, sym(tree)));
+    printf("NODE_COLON3: ::%s\n", mrb_sym_name(mrb, sym(tree)));
     break;
 
   case NODE_ARRAY:
@@ -6606,7 +6999,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     mrb_parser_dump(mrb, tree->car, offset+2);
     tree = tree->cdr;
     dump_prefix(tree, offset+1);
-    printf("op='%s' (%d)\n", mrb_sym2name(mrb, sym(tree->car)), intn(tree->car));
+    printf("op='%s' (%d)\n", mrb_sym_name(mrb, sym(tree->car)), intn(tree->car));
     tree = tree->cdr;
     mrb_parser_dump(mrb, tree->car, offset+1);
     break;
@@ -6658,23 +7051,27 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     break;
 
   case NODE_LVAR:
-    printf("NODE_LVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+    printf("NODE_LVAR %s\n", mrb_sym_name(mrb, sym(tree)));
     break;
 
   case NODE_GVAR:
-    printf("NODE_GVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+    printf("NODE_GVAR %s\n", mrb_sym_name(mrb, sym(tree)));
     break;
 
   case NODE_IVAR:
-    printf("NODE_IVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+    printf("NODE_IVAR %s\n", mrb_sym_name(mrb, sym(tree)));
     break;
 
   case NODE_CVAR:
-    printf("NODE_CVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+    printf("NODE_CVAR %s\n", mrb_sym_name(mrb, sym(tree)));
+    break;
+
+  case NODE_NVAR:
+    printf("NODE_NVAR %d\n", intn(tree));
     break;
 
   case NODE_CONST:
-    printf("NODE_CONST %s\n", mrb_sym2name(mrb, sym(tree)));
+    printf("NODE_CONST %s\n", mrb_sym_name(mrb, sym(tree)));
     break;
 
   case NODE_MATCH:
@@ -6696,7 +7093,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     break;
 
   case NODE_ARG:
-    printf("NODE_ARG %s\n", mrb_sym2name(mrb, sym(tree)));
+    printf("NODE_ARG %s\n", mrb_sym_name(mrb, sym(tree)));
     break;
 
   case NODE_BLOCK_ARG:
@@ -6713,25 +7110,25 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     break;
 
   case NODE_NEGATE:
-    printf("NODE_NEGATE\n");
+    printf("NODE_NEGATE:\n");
     mrb_parser_dump(mrb, tree, offset+1);
     break;
 
   case NODE_STR:
-    printf("NODE_STR \"%s\" len %d\n", (char*)tree->car, intn(tree->cdr));
+    printf("NODE_STR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr));
     break;
 
   case NODE_DSTR:
-    printf("NODE_DSTR\n");
+    printf("NODE_DSTR:\n");
     dump_recur(mrb, tree, offset+1);
     break;
 
   case NODE_XSTR:
-    printf("NODE_XSTR \"%s\" len %d\n", (char*)tree->car, intn(tree->cdr));
+    printf("NODE_XSTR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr));
     break;
 
   case NODE_DXSTR:
-    printf("NODE_DXSTR\n");
+    printf("NODE_DXSTR:\n");
     dump_recur(mrb, tree, offset+1);
     break;
 
@@ -6740,7 +7137,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     break;
 
   case NODE_DREGX:
-    printf("NODE_DREGX\n");
+    printf("NODE_DREGX:\n");
     dump_recur(mrb, tree->car, offset+1);
     dump_prefix(tree, offset);
     printf("tail: %s\n", (char*)tree->cdr->cdr->car);
@@ -6755,10 +7152,29 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     break;
 
   case NODE_SYM:
-    printf("NODE_SYM :%s (%d)\n", mrb_sym2name(mrb, sym(tree)),
+    printf("NODE_SYM :%s (%d)\n", mrb_sym_dump(mrb, sym(tree)),
            intn(tree));
     break;
 
+  case NODE_DSYM:
+    printf("NODE_DSYM:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_WORDS:
+    printf("NODE_WORDS:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_SYMBOLS:
+    printf("NODE_SYMBOLS:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_LITERAL_DELIM:
+    printf("NODE_LITERAL_DELIM\n");
+    break;
+
   case NODE_SELF:
     printf("NODE_SELF\n");
     break;
@@ -6777,8 +7193,8 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
 
   case NODE_ALIAS:
     printf("NODE_ALIAS %s %s:\n",
-        mrb_sym2name(mrb, sym(tree->car)),
-        mrb_sym2name(mrb, sym(tree->cdr)));
+        mrb_sym_dump(mrb, sym(tree->car)),
+        mrb_sym_dump(mrb, sym(tree->cdr)));
     break;
 
   case NODE_UNDEF:
@@ -6786,7 +7202,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     {
       node *t = tree;
       while (t) {
-        printf(" %s", mrb_sym2name(mrb, sym(t->car)));
+        printf(" %s", mrb_sym_dump(mrb, sym(t->car)));
         t = t->cdr;
       }
     }
@@ -6797,16 +7213,16 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     printf("NODE_CLASS:\n");
     if (tree->car->car == (node*)0) {
       dump_prefix(tree, offset+1);
-      printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+      printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
     }
     else if (tree->car->car == (node*)1) {
       dump_prefix(tree, offset+1);
-      printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
     }
     else {
       mrb_parser_dump(mrb, tree->car->car, offset+1);
       dump_prefix(tree, offset+1);
-      printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
     }
     if (tree->cdr->car) {
       dump_prefix(tree, offset+1);
@@ -6822,16 +7238,16 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     printf("NODE_MODULE:\n");
     if (tree->car->car == (node*)0) {
       dump_prefix(tree, offset+1);
-      printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+      printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
     }
     else if (tree->car->car == (node*)1) {
       dump_prefix(tree, offset+1);
-      printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
     }
     else {
       mrb_parser_dump(mrb, tree->car->car, offset+1);
       dump_prefix(tree, offset+1);
-      printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
     }
     dump_prefix(tree, offset+1);
     printf("body:\n");
@@ -6849,7 +7265,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
   case NODE_DEF:
     printf("NODE_DEF:\n");
     dump_prefix(tree, offset+1);
-    printf("%s\n", mrb_sym2name(mrb, sym(tree->car)));
+    printf("%s\n", mrb_sym_dump(mrb, sym(tree->car)));
     tree = tree->cdr;
     {
       node *n2 = tree->car;
@@ -6862,7 +7278,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
         while (n2) {
           if (n2->car) {
             if (!first_lval) printf(", ");
-            printf("%s", mrb_sym2name(mrb, sym(n2->car)));
+            printf("%s", mrb_sym_name(mrb, sym(n2->car)));
             first_lval = FALSE;
           }
           n2 = n2->cdr;
@@ -6882,7 +7298,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     mrb_parser_dump(mrb, tree->car, offset+1);
     tree = tree->cdr;
     dump_prefix(tree, offset+1);
-    printf(":%s\n", mrb_sym2name(mrb, sym(tree->car)));
+    printf(":%s\n", mrb_sym_dump(mrb, sym(tree->car)));
     tree = tree->cdr->cdr;
     if (tree->car) {
       dump_args(mrb, tree->car, offset+1);
@@ -6919,17 +7335,17 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
     tree = tree->cdr;
     if (tree->car) {
       dump_prefix(tree, offset+1);
-      printf("block='%s'\n", mrb_sym2name(mrb, sym(tree->car)));
+      printf("block='%s'\n", mrb_sym_name(mrb, sym(tree->car)));
     }
     break;
 
   case NODE_KW_ARG:
-    printf("NODE_KW_ARG %s\n", mrb_sym2name(mrb, sym(tree->car)));
+    printf("NODE_KW_ARG %s:\n", mrb_sym_name(mrb, sym(tree->car)));
     mrb_parser_dump(mrb, tree->cdr->car, offset + 1);
     break;
 
   case NODE_KW_REST_ARGS:
-    printf("NODE_KW_REST_ARGS %s\n", mrb_sym2name(mrb, sym(tree)));
+    printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree)));
     break;
 
   default:
diff --git a/third-party/mruby/mrbgems/mruby-compiler/core/y.tab.c b/third-party/mruby/mrbgems/mruby-compiler/core/y.tab.c
new file mode 100644 (file)
index 0000000..a22846e
--- /dev/null
@@ -0,0 +1,13153 @@
+/* A Bison parser, made by GNU Bison 3.5.1.  */
+
+/* Bison implementation for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
+   Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "3.5.1"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Push parsers.  */
+#define YYPUSH 0
+
+/* Pull parsers.  */
+#define YYPULL 1
+
+
+
+
+/* First part of user prologue.  */
+#line 7 "mrbgems/mruby-compiler/core/parse.y"
+
+#undef PARSER_DEBUG
+#ifdef PARSER_DEBUG
+# define YYDEBUG 1
+#endif
+#define YYSTACK_USE_ALLOCA 1
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/compile.h>
+#include <mruby/proc.h>
+#include <mruby/error.h>
+#include <mruby/throw.h>
+#include <mruby/string.h>
+#include "node.h"
+
+#define YYLEX_PARAM p
+
+typedef mrb_ast_node node;
+typedef struct mrb_parser_state parser_state;
+typedef struct mrb_parser_heredoc_info parser_heredoc_info;
+
+static int yyparse(parser_state *p);
+static int yylex(void *lval, parser_state *p);
+static void yyerror(parser_state *p, const char *s);
+static void yywarn(parser_state *p, const char *s);
+static void yywarning(parser_state *p, const char *s);
+static void backref_error(parser_state *p, node *n);
+static void void_expr_error(parser_state *p, node *n);
+static void tokadd(parser_state *p, int32_t c);
+
+#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
+
+typedef unsigned int stack_type;
+
+#define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1))
+#define BITSTACK_POP(stack)     ((stack) = (stack) >> 1)
+#define BITSTACK_LEXPOP(stack)  ((stack) = ((stack) >> 1) | ((stack) & 1))
+#define BITSTACK_SET_P(stack)   ((stack)&1)
+
+#define COND_PUSH(n)    BITSTACK_PUSH(p->cond_stack, (n))
+#define COND_POP()      BITSTACK_POP(p->cond_stack)
+#define COND_LEXPOP()   BITSTACK_LEXPOP(p->cond_stack)
+#define COND_P()        BITSTACK_SET_P(p->cond_stack)
+
+#define CMDARG_PUSH(n)  BITSTACK_PUSH(p->cmdarg_stack, (n))
+#define CMDARG_POP()    BITSTACK_POP(p->cmdarg_stack)
+#define CMDARG_LEXPOP() BITSTACK_LEXPOP(p->cmdarg_stack)
+#define CMDARG_P()      BITSTACK_SET_P(p->cmdarg_stack)
+
+#define SET_LINENO(c,n) ((c)->lineno = (n))
+#define NODE_LINENO(c,n) do {\
+  if (n) {\
+     (c)->filename_index = (n)->filename_index;\
+     (c)->lineno = (n)->lineno;\
+  }\
+} while (0)
+
+#define sym(x) ((mrb_sym)(intptr_t)(x))
+#define nsym(x) ((node*)(intptr_t)(x))
+#define nint(x) ((node*)(intptr_t)(x))
+#define intn(x) ((int)(intptr_t)(x))
+
+#define NUM_SUFFIX_R   (1<<0)
+#define NUM_SUFFIX_I   (1<<1)
+
+static inline mrb_sym
+intern_cstr_gen(parser_state *p, const char *s)
+{
+  return mrb_intern_cstr(p->mrb, s);
+}
+#define intern_cstr(s) intern_cstr_gen(p,(s))
+
+static inline mrb_sym
+intern_gen(parser_state *p, const char *s, size_t len)
+{
+  return mrb_intern(p->mrb, s, len);
+}
+#define intern(s,len) intern_gen(p,(s),(len))
+
+#define intern_lit(s) mrb_intern_lit(p->mrb, s)
+
+static void
+cons_free_gen(parser_state *p, node *cons)
+{
+  cons->cdr = p->cells;
+  p->cells = cons;
+}
+#define cons_free(c) cons_free_gen(p, (c))
+
+static void*
+parser_palloc(parser_state *p, size_t size)
+{
+  void *m = mrb_pool_alloc(p->pool, size);
+
+  if (!m) {
+    MRB_THROW(p->jmp);
+  }
+  return m;
+}
+
+static node*
+cons_gen(parser_state *p, node *car, node *cdr)
+{
+  node *c;
+
+  if (p->cells) {
+    c = p->cells;
+    p->cells = p->cells->cdr;
+  }
+  else {
+    c = (node *)parser_palloc(p, sizeof(mrb_ast_node));
+  }
+
+  c->car = car;
+  c->cdr = cdr;
+  c->lineno = p->lineno;
+  c->filename_index = p->current_filename_index;
+  /* beginning of next partial file; need to point the previous file */
+  if (p->lineno == 0 && p->current_filename_index > 0) {
+    c->filename_index-- ;
+  }
+  return c;
+}
+#define cons(a,b) cons_gen(p,(a),(b))
+
+static node*
+list1_gen(parser_state *p, node *a)
+{
+  return cons(a, 0);
+}
+#define list1(a) list1_gen(p, (a))
+
+static node*
+list2_gen(parser_state *p, node *a, node *b)
+{
+  return cons(a, cons(b,0));
+}
+#define list2(a,b) list2_gen(p, (a),(b))
+
+static node*
+list3_gen(parser_state *p, node *a, node *b, node *c)
+{
+  return cons(a, cons(b, cons(c,0)));
+}
+#define list3(a,b,c) list3_gen(p, (a),(b),(c))
+
+static node*
+list4_gen(parser_state *p, node *a, node *b, node *c, node *d)
+{
+  return cons(a, cons(b, cons(c, cons(d, 0))));
+}
+#define list4(a,b,c,d) list4_gen(p, (a),(b),(c),(d))
+
+static node*
+list5_gen(parser_state *p, node *a, node *b, node *c, node *d, node *e)
+{
+  return cons(a, cons(b, cons(c, cons(d, cons(e, 0)))));
+}
+#define list5(a,b,c,d,e) list5_gen(p, (a),(b),(c),(d),(e))
+
+static node*
+list6_gen(parser_state *p, node *a, node *b, node *c, node *d, node *e, node *f)
+{
+  return cons(a, cons(b, cons(c, cons(d, cons(e, cons(f, 0))))));
+}
+#define list6(a,b,c,d,e,f) list6_gen(p, (a),(b),(c),(d),(e),(f))
+
+static node*
+append_gen(parser_state *p, node *a, node *b)
+{
+  node *c = a;
+
+  if (!a) return b;
+  if (!b) return a;
+  while (c->cdr) {
+    c = c->cdr;
+  }
+  c->cdr = b;
+  return a;
+}
+#define append(a,b) append_gen(p,(a),(b))
+#define push(a,b) append_gen(p,(a),list1(b))
+
+static char*
+parser_strndup(parser_state *p, const char *s, size_t len)
+{
+  char *b = (char *)parser_palloc(p, len+1);
+
+  memcpy(b, s, len);
+  b[len] = '\0';
+  return b;
+}
+#undef strndup
+#define strndup(s,len) parser_strndup(p, s, len)
+
+static char*
+parser_strdup(parser_state *p, const char *s)
+{
+  return parser_strndup(p, s, strlen(s));
+}
+#undef strdup
+#define strdup(s) parser_strdup(p, s)
+
+static void
+dump_int(uint16_t i, char *s)
+{
+  char *p = s;
+  char *t = s;
+
+  while (i > 0) {
+    *p++ = (i % 10)+'0';
+    i /= 10;
+  }
+  if (p == s) *p++ = '0';
+  *p = 0;
+  p--;  /* point the last char */
+  while (t < p) {
+    char c = *t;
+    *t++ = *p;
+    *p-- = c;
+  }
+}
+
+/* xxx ----------------------------- */
+
+static node*
+local_switch(parser_state *p)
+{
+  node *prev = p->locals;
+
+  p->locals = cons(0, 0);
+  return prev;
+}
+
+static void
+local_resume(parser_state *p, node *prev)
+{
+  p->locals = prev;
+}
+
+static void
+local_nest(parser_state *p)
+{
+  p->locals = cons(0, p->locals);
+}
+
+static void
+local_unnest(parser_state *p)
+{
+  if (p->locals) {
+    p->locals = p->locals->cdr;
+  }
+}
+
+static mrb_bool
+local_var_p(parser_state *p, mrb_sym sym)
+{
+  struct RProc *u;
+  node *l = p->locals;
+
+  while (l) {
+    node *n = l->car;
+    while (n) {
+      if (sym(n->car) == sym) return TRUE;
+      n = n->cdr;
+    }
+    l = l->cdr;
+  }
+
+  u = p->upper;
+  while (u && !MRB_PROC_CFUNC_P(u)) {
+    struct mrb_irep *ir = u->body.irep;
+    uint_fast16_t n = ir->nlocals;
+    const struct mrb_locals *v = ir->lv;
+    for (; n > 1; n --, v ++) {
+      if (v->name == sym) return TRUE;
+    }
+    if (MRB_PROC_SCOPE_P(u)) break;
+    u = u->upper;
+  }
+  return FALSE;
+}
+
+static void
+local_add_f(parser_state *p, mrb_sym sym)
+{
+  if (p->locals) {
+    p->locals->car = push(p->locals->car, nsym(sym));
+  }
+}
+
+static void
+local_add(parser_state *p, mrb_sym sym)
+{
+  if (!local_var_p(p, sym)) {
+    local_add_f(p, sym);
+  }
+}
+
+static void
+local_add_blk(parser_state *p, mrb_sym blk)
+{
+  /* allocate register for block */
+  local_add_f(p, blk ? blk : mrb_intern_lit(p->mrb, "&"));
+}
+
+static void
+local_add_kw(parser_state *p, mrb_sym kwd)
+{
+  /* allocate register for keywords hash */
+  local_add_f(p, kwd ? kwd : mrb_intern_lit(p->mrb, "**"));
+}
+
+static node*
+locals_node(parser_state *p)
+{
+  return p->locals ? p->locals->car : NULL;
+}
+
+static void
+nvars_nest(parser_state *p)
+{
+  p->nvars = cons(nint(0), p->nvars);
+}
+
+static void
+nvars_block(parser_state *p)
+{
+  p->nvars = cons(nint(-2), p->nvars);
+}
+
+static void
+nvars_unnest(parser_state *p)
+{
+  p->nvars = p->nvars->cdr;
+}
+
+/* (:scope (vars..) (prog...)) */
+static node*
+new_scope(parser_state *p, node *body)
+{
+  return cons((node*)NODE_SCOPE, cons(locals_node(p), body));
+}
+
+/* (:begin prog...) */
+static node*
+new_begin(parser_state *p, node *body)
+{
+  if (body) {
+    return list2((node*)NODE_BEGIN, body);
+  }
+  return cons((node*)NODE_BEGIN, 0);
+}
+
+#define newline_node(n) (n)
+
+/* (:rescue body rescue else) */
+static node*
+new_rescue(parser_state *p, node *body, node *resq, node *els)
+{
+  return list4((node*)NODE_RESCUE, body, resq, els);
+}
+
+static node*
+new_mod_rescue(parser_state *p, node *body, node *resq)
+{
+  return new_rescue(p, body, list1(list3(0, 0, resq)), 0);
+}
+
+/* (:ensure body ensure) */
+static node*
+new_ensure(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_ENSURE, cons(a, cons(0, b)));
+}
+
+/* (:nil) */
+static node*
+new_nil(parser_state *p)
+{
+  return list1((node*)NODE_NIL);
+}
+
+/* (:true) */
+static node*
+new_true(parser_state *p)
+{
+  return list1((node*)NODE_TRUE);
+}
+
+/* (:false) */
+static node*
+new_false(parser_state *p)
+{
+  return list1((node*)NODE_FALSE);
+}
+
+/* (:alias new old) */
+static node*
+new_alias(parser_state *p, mrb_sym a, mrb_sym b)
+{
+  return cons((node*)NODE_ALIAS, cons(nsym(a), nsym(b)));
+}
+
+/* (:if cond then else) */
+static node*
+new_if(parser_state *p, node *a, node *b, node *c)
+{
+  void_expr_error(p, a);
+  return list4((node*)NODE_IF, a, b, c);
+}
+
+/* (:unless cond then else) */
+static node*
+new_unless(parser_state *p, node *a, node *b, node *c)
+{
+  void_expr_error(p, a);
+  return list4((node*)NODE_IF, a, c, b);
+}
+
+/* (:while cond body) */
+static node*
+new_while(parser_state *p, node *a, node *b)
+{
+  void_expr_error(p, a);
+  return cons((node*)NODE_WHILE, cons(a, b));
+}
+
+/* (:until cond body) */
+static node*
+new_until(parser_state *p, node *a, node *b)
+{
+  void_expr_error(p, a);
+  return cons((node*)NODE_UNTIL, cons(a, b));
+}
+
+/* (:for var obj body) */
+static node*
+new_for(parser_state *p, node *v, node *o, node *b)
+{
+  void_expr_error(p, o);
+  return list4((node*)NODE_FOR, v, o, b);
+}
+
+/* (:case a ((when ...) body) ((when...) body)) */
+static node*
+new_case(parser_state *p, node *a, node *b)
+{
+  node *n = list2((node*)NODE_CASE, a);
+  node *n2 = n;
+
+  void_expr_error(p, a);
+  while (n2->cdr) {
+    n2 = n2->cdr;
+  }
+  n2->cdr = b;
+  return n;
+}
+
+/* (:postexe a) */
+static node*
+new_postexe(parser_state *p, node *a)
+{
+  return cons((node*)NODE_POSTEXE, a);
+}
+
+/* (:self) */
+static node*
+new_self(parser_state *p)
+{
+  return list1((node*)NODE_SELF);
+}
+
+/* (:call a b c) */
+static node*
+new_call(parser_state *p, node *a, mrb_sym b, node *c, int pass)
+{
+  node *n = list4(nint(pass?NODE_CALL:NODE_SCALL), a, nsym(b), c);
+  void_expr_error(p, a);
+  NODE_LINENO(n, a);
+  return n;
+}
+
+/* (:fcall self mid args) */
+static node*
+new_fcall(parser_state *p, mrb_sym b, node *c)
+{
+  node *n = new_self(p);
+  NODE_LINENO(n, c);
+  n = list4((node*)NODE_FCALL, n, nsym(b), c);
+  NODE_LINENO(n, c);
+  return n;
+}
+
+/* (:super . c) */
+static node*
+new_super(parser_state *p, node *c)
+{
+  return cons((node*)NODE_SUPER, c);
+}
+
+/* (:zsuper) */
+static node*
+new_zsuper(parser_state *p)
+{
+  return list1((node*)NODE_ZSUPER);
+}
+
+/* (:yield . c) */
+static node*
+new_yield(parser_state *p, node *c)
+{
+  if (c) {
+    if (c->cdr) {
+      yyerror(p, "both block arg and actual block given");
+    }
+    return cons((node*)NODE_YIELD, c->car);
+  }
+  return cons((node*)NODE_YIELD, 0);
+}
+
+/* (:return . c) */
+static node*
+new_return(parser_state *p, node *c)
+{
+  return cons((node*)NODE_RETURN, c);
+}
+
+/* (:break . c) */
+static node*
+new_break(parser_state *p, node *c)
+{
+  return cons((node*)NODE_BREAK, c);
+}
+
+/* (:next . c) */
+static node*
+new_next(parser_state *p, node *c)
+{
+  return cons((node*)NODE_NEXT, c);
+}
+
+/* (:redo) */
+static node*
+new_redo(parser_state *p)
+{
+  return list1((node*)NODE_REDO);
+}
+
+/* (:retry) */
+static node*
+new_retry(parser_state *p)
+{
+  return list1((node*)NODE_RETRY);
+}
+
+/* (:dot2 a b) */
+static node*
+new_dot2(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_DOT2, cons(a, b));
+}
+
+/* (:dot3 a b) */
+static node*
+new_dot3(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_DOT3, cons(a, b));
+}
+
+/* (:colon2 b c) */
+static node*
+new_colon2(parser_state *p, node *b, mrb_sym c)
+{
+  void_expr_error(p, b);
+  return cons((node*)NODE_COLON2, cons(b, nsym(c)));
+}
+
+/* (:colon3 . c) */
+static node*
+new_colon3(parser_state *p, mrb_sym c)
+{
+  return cons((node*)NODE_COLON3, nsym(c));
+}
+
+/* (:and a b) */
+static node*
+new_and(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_AND, cons(a, b));
+}
+
+/* (:or a b) */
+static node*
+new_or(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_OR, cons(a, b));
+}
+
+/* (:array a...) */
+static node*
+new_array(parser_state *p, node *a)
+{
+  return cons((node*)NODE_ARRAY, a);
+}
+
+/* (:splat . a) */
+static node*
+new_splat(parser_state *p, node *a)
+{
+  return cons((node*)NODE_SPLAT, a);
+}
+
+/* (:hash (k . v) (k . v)...) */
+static node*
+new_hash(parser_state *p, node *a)
+{
+  return cons((node*)NODE_HASH, a);
+}
+
+/* (:kw_hash (k . v) (k . v)...) */
+static node*
+new_kw_hash(parser_state *p, node *a)
+{
+  return cons((node*)NODE_KW_HASH, a);
+}
+
+/* (:sym . a) */
+static node*
+new_sym(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_SYM, nsym(sym));
+}
+
+static mrb_sym
+new_strsym(parser_state *p, node* str)
+{
+  const char *s = (const char*)str->cdr->car;
+  size_t len = (size_t)str->cdr->cdr;
+
+  return mrb_intern(p->mrb, s, len);
+}
+
+/* (:lvar . a) */
+static node*
+new_lvar(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_LVAR, nsym(sym));
+}
+
+/* (:gvar . a) */
+static node*
+new_gvar(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_GVAR, nsym(sym));
+}
+
+/* (:ivar . a) */
+static node*
+new_ivar(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_IVAR, nsym(sym));
+}
+
+/* (:cvar . a) */
+static node*
+new_cvar(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_CVAR, nsym(sym));
+}
+
+/* (:nvar . a) */
+static node*
+new_nvar(parser_state *p, int num)
+{
+  int nvars = intn(p->nvars->car);
+
+  p->nvars->car = nint(nvars > num ? nvars : num);
+  return cons((node*)NODE_NVAR, nint(num));
+}
+
+/* (:const . a) */
+static node*
+new_const(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_CONST, nsym(sym));
+}
+
+/* (:undef a...) */
+static node*
+new_undef(parser_state *p, mrb_sym sym)
+{
+  return list2((node*)NODE_UNDEF, nsym(sym));
+}
+
+/* (:class class super body) */
+static node*
+new_class(parser_state *p, node *c, node *s, node *b)
+{
+  void_expr_error(p, s);
+  return list4((node*)NODE_CLASS, c, s, cons(locals_node(p), b));
+}
+
+/* (:sclass obj body) */
+static node*
+new_sclass(parser_state *p, node *o, node *b)
+{
+  void_expr_error(p, o);
+  return list3((node*)NODE_SCLASS, o, cons(locals_node(p), b));
+}
+
+/* (:module module body) */
+static node*
+new_module(parser_state *p, node *m, node *b)
+{
+  return list3((node*)NODE_MODULE, m, cons(locals_node(p), b));
+}
+
+/* (:def m lv (arg . body)) */
+static node*
+new_def(parser_state *p, mrb_sym m, node *a, node *b)
+{
+  return list5((node*)NODE_DEF, nsym(m), locals_node(p), a, b);
+}
+
+/* (:sdef obj m lv (arg . body)) */
+static node*
+new_sdef(parser_state *p, node *o, mrb_sym m, node *a, node *b)
+{
+  void_expr_error(p, o);
+  return list6((node*)NODE_SDEF, o, nsym(m), locals_node(p), a, b);
+}
+
+/* (:arg . sym) */
+static node*
+new_arg(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_ARG, nsym(sym));
+}
+
+static void
+local_add_margs(parser_state *p, node *n)
+{
+  while (n) {
+    if (n->car->car == (node*)NODE_MASGN) {
+      node *t = n->car->cdr->cdr;
+
+      n->car->cdr->cdr = NULL;
+      while (t) {
+        local_add_f(p, sym(t->car));
+        t = t->cdr;
+      }
+      local_add_margs(p, n->car->cdr->car->car);
+      local_add_margs(p, n->car->cdr->car->cdr->cdr->car);
+    }
+    n = n->cdr;
+  }
+}
+
+static void
+local_add_lv(parser_state *p, node *lv)
+{
+  while (lv) {
+    local_add_f(p, sym(lv->car));
+    lv = lv->cdr;
+  }
+}
+
+/* (m o r m2 tail) */
+/* m: (a b c) */
+/* o: ((a . e1) (b . e2)) */
+/* r: a */
+/* m2: (a b c) */
+/* b: a */
+static node*
+new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, node *tail)
+{
+  node *n;
+
+  local_add_margs(p, m);
+  local_add_margs(p, m2);
+  n = cons(m2, tail);
+  n = cons(nsym(rest), n);
+  n = cons(opt, n);
+  while (opt) {
+    /* opt: (sym . (opt . lv)) -> (sym . opt) */
+    local_add_lv(p, opt->car->cdr->cdr);
+    opt->car->cdr = opt->car->cdr->car;
+    opt = opt->cdr;
+  }
+  return cons(m, n);
+}
+
+/* (:args_tail keywords rest_keywords_sym block_sym) */
+static node*
+new_args_tail(parser_state *p, node *kws, node *kwrest, mrb_sym blk)
+{
+  node *k;
+
+  if (kws || kwrest) {
+    local_add_kw(p, (kwrest && kwrest->cdr)? sym(kwrest->cdr) : 0);
+  }
+
+  local_add_blk(p, blk);
+
+  /* allocate register for keywords arguments */
+  /* order is for Proc#parameters */
+  for (k = kws; k; k = k->cdr) {
+    if (!k->car->cdr->cdr->car) { /* allocate required keywords */
+      local_add_f(p, sym(k->car->cdr->car));
+    }
+  }
+  for (k = kws; k; k = k->cdr) {
+    if (k->car->cdr->cdr->car) { /* allocate keywords with default */
+      local_add_lv(p, k->car->cdr->cdr->car->cdr);
+      k->car->cdr->cdr->car = k->car->cdr->cdr->car->car;
+      local_add_f(p, sym(k->car->cdr->car));
+    }
+  }
+
+  return list4((node*)NODE_ARGS_TAIL, kws, kwrest, nsym(blk));
+}
+
+/* (:kw_arg kw_sym def_arg) */
+static node*
+new_kw_arg(parser_state *p, mrb_sym kw, node *def_arg)
+{
+  mrb_assert(kw);
+  return list3((node*)NODE_KW_ARG, nsym(kw), def_arg);
+}
+
+/* (:kw_rest_args . a) */
+static node*
+new_kw_rest_args(parser_state *p, node *a)
+{
+  return cons((node*)NODE_KW_REST_ARGS, a);
+}
+
+/* (:block_arg . a) */
+static node*
+new_block_arg(parser_state *p, node *a)
+{
+  return cons((node*)NODE_BLOCK_ARG, a);
+}
+
+static node*
+setup_numparams(parser_state *p, node *a)
+{
+  int nvars = intn(p->nvars->car);
+  if (nvars > 0) {
+    int i;
+    mrb_sym sym;
+    // m || opt || rest || tail
+    if (a && (a->car || (a->cdr && a->cdr->car) || (a->cdr->cdr && a->cdr->cdr->car) || (a->cdr->cdr->cdr->cdr && a->cdr->cdr->cdr->cdr->car))) {
+      yyerror(p, "ordinary parameter is defined");
+    }
+    else if (p->locals) {
+      /* p->locals should not be NULL unless error happens before the point */
+      node* args = 0;
+      for (i = nvars; i > 0; i--) {
+        char buf[3];
+
+        buf[0] = '_';
+        buf[1] = i+'0';
+        buf[2] = '\0';
+        sym = intern_cstr(buf);
+        args = cons(new_arg(p, sym), args);
+        p->locals->car = cons(nsym(sym), p->locals->car);
+      }
+      a = new_args(p, args, 0, 0, 0, 0);
+    }
+  }
+  return a;
+}
+
+/* (:block arg body) */
+static node*
+new_block(parser_state *p, node *a, node *b)
+{
+  a = setup_numparams(p, a);
+  return list4((node*)NODE_BLOCK, locals_node(p), a, b);
+}
+
+/* (:lambda arg body) */
+static node*
+new_lambda(parser_state *p, node *a, node *b)
+{
+  return list4((node*)NODE_LAMBDA, locals_node(p), a, b);
+}
+
+/* (:asgn lhs rhs) */
+static node*
+new_asgn(parser_state *p, node *a, node *b)
+{
+  void_expr_error(p, b);
+  return cons((node*)NODE_ASGN, cons(a, b));
+}
+
+/* (:masgn mlhs=(pre rest post)  mrhs) */
+static node*
+new_masgn(parser_state *p, node *a, node *b)
+{
+  void_expr_error(p, b);
+  return cons((node*)NODE_MASGN, cons(a, b));
+}
+
+/* (:masgn mlhs mrhs) no check */
+static node*
+new_masgn_param(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_MASGN, cons(a, b));
+}
+
+/* (:asgn lhs rhs) */
+static node*
+new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b)
+{
+  void_expr_error(p, b);
+  return list4((node*)NODE_OP_ASGN, a, nsym(op), b);
+}
+
+static node*
+new_imaginary(parser_state *p, node *imaginary)
+{
+  return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Complex"), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1);
+}
+
+static node*
+new_rational(parser_state *p, node *rational)
+{
+  return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Rational"), list1(list1(rational)), 1);
+}
+
+/* (:int . i) */
+static node*
+new_int(parser_state *p, const char *s, int base, int suffix)
+{
+  node* result = list3((node*)NODE_INT, (node*)strdup(s), nint(base));
+  if (suffix & NUM_SUFFIX_R) {
+    result = new_rational(p, result);
+  }
+  if (suffix & NUM_SUFFIX_I) {
+    result = new_imaginary(p, result);
+  }
+  return result;
+}
+
+#ifndef MRB_WITHOUT_FLOAT
+/* (:float . i) */
+static node*
+new_float(parser_state *p, const char *s, int suffix)
+{
+  node* result = cons((node*)NODE_FLOAT, (node*)strdup(s));
+  if (suffix & NUM_SUFFIX_R) {
+    result = new_rational(p, result);
+  }
+  if (suffix & NUM_SUFFIX_I) {
+    result = new_imaginary(p, result);
+  }
+  return result;
+}
+#endif
+
+/* (:str . (s . len)) */
+static node*
+new_str(parser_state *p, const char *s, size_t len)
+{
+  return cons((node*)NODE_STR, cons((node*)strndup(s, len), nint(len)));
+}
+
+/* (:dstr . a) */
+static node*
+new_dstr(parser_state *p, node *a)
+{
+  return cons((node*)NODE_DSTR, a);
+}
+
+static int
+string_node_p(node *n)
+{
+  return (int)((enum node_type)(intptr_t)n->car == NODE_STR);
+}
+
+static node*
+composite_string_node(parser_state *p, node *a, node *b)
+{
+  size_t newlen = (size_t)a->cdr + (size_t)b->cdr;
+  char *str = (char*)mrb_pool_realloc(p->pool, a->car, (size_t)a->cdr + 1, newlen + 1);
+  memcpy(str + (size_t)a->cdr, b->car, (size_t)b->cdr);
+  str[newlen] = '\0';
+  a->car = (node*)str;
+  a->cdr = (node*)newlen;
+  cons_free(b);
+  return a;
+}
+
+static node*
+concat_string(parser_state *p, node *a, node *b)
+{
+  if (string_node_p(a)) {
+    if (string_node_p(b)) {
+      /* a == NODE_STR && b == NODE_STR */
+      composite_string_node(p, a->cdr, b->cdr);
+      cons_free(b);
+      return a;
+    }
+    else {
+      /* a == NODE_STR && b == NODE_DSTR */
+
+      if (string_node_p(b->cdr->car)) {
+        /* a == NODE_STR && b->[NODE_STR, ...] */
+        composite_string_node(p, a->cdr, b->cdr->car->cdr);
+        cons_free(b->cdr->car);
+        b->cdr->car = a;
+        return b;
+      }
+    }
+  }
+  else {
+    node *c; /* last node of a */
+    for (c = a; c->cdr != NULL; c = c->cdr) ;
+
+    if (string_node_p(b)) {
+      /* a == NODE_DSTR && b == NODE_STR */
+      if (string_node_p(c->car)) {
+        /* a->[..., NODE_STR] && b == NODE_STR */
+        composite_string_node(p, c->car->cdr, b->cdr);
+        cons_free(b);
+        return a;
+      }
+
+      push(a, b);
+      return a;
+    }
+    else {
+      /* a == NODE_DSTR && b == NODE_DSTR */
+      if (string_node_p(c->car) && string_node_p(b->cdr->car)) {
+        /* a->[..., NODE_STR] && b->[NODE_STR, ...] */
+        node *d = b->cdr;
+        cons_free(b);
+        composite_string_node(p, c->car->cdr, d->car->cdr);
+        cons_free(d->car);
+        c->cdr = d->cdr;
+        cons_free(d);
+        return a;
+      }
+      else {
+        c->cdr = b->cdr;
+        cons_free(b);
+        return a;
+      }
+    }
+  }
+
+  return new_dstr(p, list2(a, b));
+}
+
+/* (:str . (s . len)) */
+static node*
+new_xstr(parser_state *p, const char *s, int len)
+{
+  return cons((node*)NODE_XSTR, cons((node*)strndup(s, len), nint(len)));
+}
+
+/* (:xstr . a) */
+static node*
+new_dxstr(parser_state *p, node *a)
+{
+  return cons((node*)NODE_DXSTR, a);
+}
+
+/* (:dsym . a) */
+static node*
+new_dsym(parser_state *p, node *a)
+{
+  return cons((node*)NODE_DSYM, a);
+}
+
+/* (:regx . (s . (opt . enc))) */
+static node*
+new_regx(parser_state *p, const char *p1, const char* p2, const char* p3)
+{
+  return cons((node*)NODE_REGX, cons((node*)p1, cons((node*)p2, (node*)p3)));
+}
+
+/* (:dregx . (a . b)) */
+static node*
+new_dregx(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_DREGX, cons(a, b));
+}
+
+/* (:backref . n) */
+static node*
+new_back_ref(parser_state *p, int n)
+{
+  return cons((node*)NODE_BACK_REF, nint(n));
+}
+
+/* (:nthref . n) */
+static node*
+new_nth_ref(parser_state *p, int n)
+{
+  return cons((node*)NODE_NTH_REF, nint(n));
+}
+
+/* (:heredoc . a) */
+static node*
+new_heredoc(parser_state *p)
+{
+  parser_heredoc_info *inf = (parser_heredoc_info *)parser_palloc(p, sizeof(parser_heredoc_info));
+  return cons((node*)NODE_HEREDOC, (node*)inf);
+}
+
+static void
+new_bv(parser_state *p, mrb_sym id)
+{
+}
+
+static node*
+new_literal_delim(parser_state *p)
+{
+  return cons((node*)NODE_LITERAL_DELIM, 0);
+}
+
+/* (:words . a) */
+static node*
+new_words(parser_state *p, node *a)
+{
+  return cons((node*)NODE_WORDS, a);
+}
+
+/* (:symbols . a) */
+static node*
+new_symbols(parser_state *p, node *a)
+{
+  return cons((node*)NODE_SYMBOLS, a);
+}
+
+/* xxx ----------------------------- */
+
+/* (:call a op) */
+static node*
+call_uni_op(parser_state *p, node *recv, const char *m)
+{
+  void_expr_error(p, recv);
+  return new_call(p, recv, intern_cstr(m), 0, 1);
+}
+
+/* (:call a op b) */
+static node*
+call_bin_op(parser_state *p, node *recv, const char *m, node *arg1)
+{
+  return new_call(p, recv, intern_cstr(m), list1(list1(arg1)), 1);
+}
+
+static void
+args_with_block(parser_state *p, node *a, node *b)
+{
+  if (b) {
+    if (a->cdr) {
+      yyerror(p, "both block arg and actual block given");
+    }
+    a->cdr = b;
+  }
+}
+
+static void
+call_with_block(parser_state *p, node *a, node *b)
+{
+  node *n;
+
+  switch ((enum node_type)intn(a->car)) {
+  case NODE_SUPER:
+  case NODE_ZSUPER:
+    if (!a->cdr) a->cdr = cons(0, b);
+    else {
+      args_with_block(p, a->cdr, b);
+    }
+    break;
+  case NODE_CALL:
+  case NODE_FCALL:
+  case NODE_SCALL:
+    n = a->cdr->cdr->cdr;
+    if (!n->car) n->car = cons(0, b);
+    else {
+      args_with_block(p, n->car, b);
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+static node*
+negate_lit(parser_state *p, node *n)
+{
+  return cons((node*)NODE_NEGATE, n);
+}
+
+static node*
+cond(node *n)
+{
+  return n;
+}
+
+static node*
+ret_args(parser_state *p, node *n)
+{
+  if (n->cdr) {
+    yyerror(p, "block argument should not be given");
+    return NULL;
+  }
+  if (!n->car->cdr) return n->car->car;
+  return new_array(p, n->car);
+}
+
+static void
+assignable(parser_state *p, node *lhs)
+{
+  if (intn(lhs->car) == NODE_LVAR) {
+    local_add(p, sym(lhs->cdr));
+  }
+}
+
+static node*
+var_reference(parser_state *p, node *lhs)
+{
+  node *n;
+
+  if (intn(lhs->car) == NODE_LVAR) {
+    if (!local_var_p(p, sym(lhs->cdr))) {
+      n = new_fcall(p, sym(lhs->cdr), 0);
+      cons_free(lhs);
+      return n;
+    }
+  }
+
+  return lhs;
+}
+
+typedef enum mrb_string_type  string_type;
+
+static node*
+new_strterm(parser_state *p, string_type type, int term, int paren)
+{
+  return cons(nint(type), cons((node*)0, cons(nint(paren), nint(term))));
+}
+
+static void
+end_strterm(parser_state *p)
+{
+  cons_free(p->lex_strterm->cdr->cdr);
+  cons_free(p->lex_strterm->cdr);
+  cons_free(p->lex_strterm);
+  p->lex_strterm = NULL;
+}
+
+static parser_heredoc_info *
+parsing_heredoc_inf(parser_state *p)
+{
+  node *nd = p->parsing_heredoc;
+  if (nd == NULL)
+    return NULL;
+  /* mrb_assert(nd->car->car == NODE_HEREDOC); */
+  return (parser_heredoc_info*)nd->car->cdr;
+}
+
+static void
+heredoc_treat_nextline(parser_state *p)
+{
+  if (p->heredocs_from_nextline == NULL)
+    return;
+  if (p->parsing_heredoc == NULL) {
+    node *n;
+    p->parsing_heredoc = p->heredocs_from_nextline;
+    p->lex_strterm_before_heredoc = p->lex_strterm;
+    p->lex_strterm = new_strterm(p, parsing_heredoc_inf(p)->type, 0, 0);
+    n = p->all_heredocs;
+    if (n) {
+      while (n->cdr)
+        n = n->cdr;
+      n->cdr = p->parsing_heredoc;
+    }
+    else {
+      p->all_heredocs = p->parsing_heredoc;
+    }
+  }
+  else {
+    node *n, *m;
+    m = p->heredocs_from_nextline;
+    while (m->cdr)
+      m = m->cdr;
+    n = p->all_heredocs;
+    mrb_assert(n != NULL);
+    if (n == p->parsing_heredoc) {
+      m->cdr = n;
+      p->all_heredocs = p->heredocs_from_nextline;
+      p->parsing_heredoc = p->heredocs_from_nextline;
+    }
+    else {
+      while (n->cdr != p->parsing_heredoc) {
+        n = n->cdr;
+        mrb_assert(n != NULL);
+      }
+      m->cdr = n->cdr;
+      n->cdr = p->heredocs_from_nextline;
+      p->parsing_heredoc = p->heredocs_from_nextline;
+    }
+  }
+  p->heredocs_from_nextline = NULL;
+}
+
+static void
+heredoc_end(parser_state *p)
+{
+  p->parsing_heredoc = p->parsing_heredoc->cdr;
+  if (p->parsing_heredoc == NULL) {
+    p->lstate = EXPR_BEG;
+    end_strterm(p);
+    p->lex_strterm = p->lex_strterm_before_heredoc;
+    p->lex_strterm_before_heredoc = NULL;
+  }
+  else {
+    /* next heredoc */
+    p->lex_strterm->car = nint(parsing_heredoc_inf(p)->type);
+  }
+}
+#define is_strterm_type(p,str_func) (intn((p)->lex_strterm->car) & (str_func))
+
+/* xxx ----------------------------- */
+
+
+#line 1408 "mrbgems/mruby-compiler/core/y.tab.c"
+
+# ifndef YY_CAST
+#  ifdef __cplusplus
+#   define YY_CAST(Type, Val) static_cast<Type> (Val)
+#   define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
+#  else
+#   define YY_CAST(Type, Val) ((Type) (Val))
+#   define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
+#  endif
+# endif
+# ifndef YY_NULLPTR
+#  if defined __cplusplus
+#   if 201103L <= __cplusplus
+#    define YY_NULLPTR nullptr
+#   else
+#    define YY_NULLPTR 0
+#   endif
+#  else
+#   define YY_NULLPTR ((void*)0)
+#  endif
+# endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+  enum yytokentype
+  {
+    keyword_class = 258,
+    keyword_module = 259,
+    keyword_def = 260,
+    keyword_begin = 261,
+    keyword_if = 262,
+    keyword_unless = 263,
+    keyword_while = 264,
+    keyword_until = 265,
+    keyword_for = 266,
+    keyword_undef = 267,
+    keyword_rescue = 268,
+    keyword_ensure = 269,
+    keyword_end = 270,
+    keyword_then = 271,
+    keyword_elsif = 272,
+    keyword_else = 273,
+    keyword_case = 274,
+    keyword_when = 275,
+    keyword_break = 276,
+    keyword_next = 277,
+    keyword_redo = 278,
+    keyword_retry = 279,
+    keyword_in = 280,
+    keyword_do = 281,
+    keyword_do_cond = 282,
+    keyword_do_block = 283,
+    keyword_do_LAMBDA = 284,
+    keyword_return = 285,
+    keyword_yield = 286,
+    keyword_super = 287,
+    keyword_self = 288,
+    keyword_nil = 289,
+    keyword_true = 290,
+    keyword_false = 291,
+    keyword_and = 292,
+    keyword_or = 293,
+    keyword_not = 294,
+    modifier_if = 295,
+    modifier_unless = 296,
+    modifier_while = 297,
+    modifier_until = 298,
+    modifier_rescue = 299,
+    keyword_alias = 300,
+    keyword_BEGIN = 301,
+    keyword_END = 302,
+    keyword__LINE__ = 303,
+    keyword__FILE__ = 304,
+    keyword__ENCODING__ = 305,
+    tIDENTIFIER = 306,
+    tFID = 307,
+    tGVAR = 308,
+    tIVAR = 309,
+    tCONSTANT = 310,
+    tCVAR = 311,
+    tLABEL_TAG = 312,
+    tINTEGER = 313,
+    tFLOAT = 314,
+    tCHAR = 315,
+    tXSTRING = 316,
+    tREGEXP = 317,
+    tSTRING = 318,
+    tSTRING_PART = 319,
+    tSTRING_MID = 320,
+    tNTH_REF = 321,
+    tBACK_REF = 322,
+    tREGEXP_END = 323,
+    tNUMPARAM = 324,
+    tUPLUS = 325,
+    tUMINUS = 326,
+    tPOW = 327,
+    tCMP = 328,
+    tEQ = 329,
+    tEQQ = 330,
+    tNEQ = 331,
+    tGEQ = 332,
+    tLEQ = 333,
+    tANDOP = 334,
+    tOROP = 335,
+    tMATCH = 336,
+    tNMATCH = 337,
+    tDOT2 = 338,
+    tDOT3 = 339,
+    tAREF = 340,
+    tASET = 341,
+    tLSHFT = 342,
+    tRSHFT = 343,
+    tCOLON2 = 344,
+    tCOLON3 = 345,
+    tOP_ASGN = 346,
+    tASSOC = 347,
+    tLPAREN = 348,
+    tLPAREN_ARG = 349,
+    tRPAREN = 350,
+    tLBRACK = 351,
+    tLBRACE = 352,
+    tLBRACE_ARG = 353,
+    tSTAR = 354,
+    tDSTAR = 355,
+    tAMPER = 356,
+    tLAMBDA = 357,
+    tANDDOT = 358,
+    tSYMBEG = 359,
+    tREGEXP_BEG = 360,
+    tWORDS_BEG = 361,
+    tSYMBOLS_BEG = 362,
+    tSTRING_BEG = 363,
+    tXSTRING_BEG = 364,
+    tSTRING_DVAR = 365,
+    tLAMBEG = 366,
+    tHEREDOC_BEG = 367,
+    tHEREDOC_END = 368,
+    tLITERAL_DELIM = 369,
+    tHD_LITERAL_DELIM = 370,
+    tHD_STRING_PART = 371,
+    tHD_STRING_MID = 372,
+    tLOWEST = 373,
+    tUMINUS_NUM = 374,
+    tLAST_TOKEN = 375
+  };
+#endif
+
+/* Value type.  */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+union YYSTYPE
+{
+#line 1350 "mrbgems/mruby-compiler/core/parse.y"
+
+    node *nd;
+    mrb_sym id;
+    int num;
+    stack_type stack;
+    const struct vtable *vars;
+
+#line 1586 "mrbgems/mruby-compiler/core/y.tab.c"
+
+};
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+int yyparse (parser_state *p);
+
+
+
+
+
+#ifdef short
+# undef short
+#endif
+
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+   <limits.h> and (if available) <stdint.h> are included
+   so that the code can choose integer types of a good width.  */
+
+#ifndef __PTRDIFF_MAX__
+# include <limits.h> /* INFRINGES ON USER NAME SPACE */
+# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+#  include <stdint.h> /* INFRINGES ON USER NAME SPACE */
+#  define YY_STDINT_H
+# endif
+#endif
+
+/* Narrow types that promote to a signed type and that can represent a
+   signed or unsigned integer of at least N bits.  In tables they can
+   save space and decrease cache pressure.  Promoting to a signed type
+   helps avoid bugs in integer arithmetic.  */
+
+#ifdef __INT_LEAST8_MAX__
+typedef __INT_LEAST8_TYPE__ yytype_int8;
+#elif defined YY_STDINT_H
+typedef int_least8_t yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef __INT_LEAST16_MAX__
+typedef __INT_LEAST16_TYPE__ yytype_int16;
+#elif defined YY_STDINT_H
+typedef int_least16_t yytype_int16;
+#else
+typedef short yytype_int16;
+#endif
+
+#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST8_TYPE__ yytype_uint8;
+#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
+       && UINT_LEAST8_MAX <= INT_MAX)
+typedef uint_least8_t yytype_uint8;
+#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
+typedef unsigned char yytype_uint8;
+#else
+typedef short yytype_uint8;
+#endif
+
+#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST16_TYPE__ yytype_uint16;
+#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
+       && UINT_LEAST16_MAX <= INT_MAX)
+typedef uint_least16_t yytype_uint16;
+#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
+typedef unsigned short yytype_uint16;
+#else
+typedef int yytype_uint16;
+#endif
+
+#ifndef YYPTRDIFF_T
+# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
+#  define YYPTRDIFF_T __PTRDIFF_TYPE__
+#  define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
+# elif defined PTRDIFF_MAX
+#  ifndef ptrdiff_t
+#   include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  endif
+#  define YYPTRDIFF_T ptrdiff_t
+#  define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
+# else
+#  define YYPTRDIFF_T long
+#  define YYPTRDIFF_MAXIMUM LONG_MAX
+# endif
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM                                  \
+  YY_CAST (YYPTRDIFF_T,                                 \
+           (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1)  \
+            ? YYPTRDIFF_MAXIMUM                         \
+            : YY_CAST (YYSIZE_T, -1)))
+
+#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
+
+/* Stored state numbers (used for stacks). */
+typedef yytype_int16 yy_state_t;
+
+/* State numbers in computations.  */
+typedef int yy_state_fast_t;
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+#  define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
+# else
+#  define YY_ATTRIBUTE_PURE
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+#  define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+# else
+#  define YY_ATTRIBUTE_UNUSED
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                            \
+    _Pragma ("GCC diagnostic push")                                     \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")              \
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END      \
+    _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN                          \
+    _Pragma ("GCC diagnostic push")                            \
+    _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END            \
+    _Pragma ("GCC diagnostic pop")
+#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's 'empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
+       && ! ((defined YYMALLOC || defined malloc) \
+             && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yy_state_t yyss_alloc;
+  YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
+      + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
+    do                                                                  \
+      {                                                                 \
+        YYPTRDIFF_T yynewbytes;                                         \
+        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+        Stack = &yyptr->Stack_alloc;                                    \
+        yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
+        yyptr += yynewbytes / YYSIZEOF (*yyptr);                        \
+      }                                                                 \
+    while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYPTRDIFF_T yyi;                      \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (0)
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  3
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   11586
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  147
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  176
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  594
+/* YYNSTATES -- Number of states.  */
+#define YYNSTATES  1034
+
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   375
+
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, with out-of-bounds checking.  */
+#define YYTRANSLATE(YYX)                                                \
+  (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     146,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,   133,     2,     2,     2,   131,   126,     2,
+     142,   143,   129,   127,   140,   128,   145,   130,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,   121,   144,
+     123,   119,   122,   120,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,   138,     2,   139,   125,     2,   141,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,   136,   124,   137,   134,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
+      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
+      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
+      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
+     105,   106,   107,   108,   109,   110,   111,   112,   113,   114,
+     115,   116,   117,   118,   132,   135
+};
+
+#if YYDEBUG
+  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
+static const yytype_int16 yyrline[] =
+{
+       0,  1508,  1508,  1508,  1519,  1525,  1529,  1534,  1538,  1544,
+    1546,  1545,  1559,  1586,  1592,  1596,  1601,  1605,  1611,  1611,
+    1615,  1619,  1623,  1627,  1631,  1635,  1639,  1644,  1645,  1649,
+    1653,  1657,  1661,  1664,  1668,  1672,  1676,  1680,  1684,  1689,
+    1693,  1700,  1701,  1705,  1709,  1710,  1714,  1718,  1722,  1726,
+    1729,  1738,  1739,  1742,  1743,  1750,  1749,  1764,  1768,  1773,
+    1777,  1782,  1786,  1791,  1795,  1799,  1803,  1807,  1813,  1817,
+    1823,  1824,  1830,  1834,  1838,  1842,  1846,  1850,  1854,  1858,
+    1862,  1866,  1872,  1873,  1879,  1883,  1889,  1893,  1899,  1903,
+    1907,  1911,  1915,  1919,  1925,  1931,  1938,  1942,  1946,  1950,
+    1954,  1958,  1964,  1970,  1975,  1981,  1985,  1988,  1992,  1996,
+    2003,  2004,  2005,  2006,  2011,  2018,  2019,  2022,  2026,  2026,
+    2032,  2033,  2034,  2035,  2036,  2037,  2038,  2039,  2040,  2041,
+    2042,  2043,  2044,  2045,  2046,  2047,  2048,  2049,  2050,  2051,
+    2052,  2053,  2054,  2055,  2056,  2057,  2058,  2059,  2060,  2061,
+    2064,  2064,  2064,  2065,  2065,  2066,  2066,  2066,  2067,  2067,
+    2067,  2067,  2068,  2068,  2068,  2069,  2069,  2069,  2070,  2070,
+    2070,  2070,  2071,  2071,  2071,  2071,  2072,  2072,  2072,  2072,
+    2073,  2073,  2073,  2073,  2074,  2074,  2074,  2074,  2075,  2075,
+    2078,  2082,  2086,  2090,  2094,  2098,  2102,  2107,  2112,  2117,
+    2121,  2125,  2129,  2133,  2137,  2141,  2145,  2149,  2153,  2157,
+    2161,  2165,  2169,  2173,  2177,  2181,  2185,  2189,  2193,  2197,
+    2201,  2205,  2209,  2213,  2217,  2221,  2225,  2229,  2233,  2237,
+    2241,  2245,  2249,  2255,  2256,  2261,  2265,  2272,  2276,  2284,
+    2288,  2314,  2315,  2318,  2319,  2320,  2325,  2330,  2337,  2343,
+    2348,  2353,  2358,  2365,  2365,  2376,  2382,  2386,  2392,  2393,
+    2396,  2402,  2408,  2413,  2420,  2425,  2430,  2437,  2438,  2439,
+    2440,  2441,  2442,  2443,  2444,  2448,  2453,  2452,  2464,  2468,
+    2463,  2473,  2473,  2477,  2481,  2485,  2489,  2494,  2499,  2503,
+    2507,  2511,  2515,  2519,  2520,  2526,  2532,  2525,  2544,  2552,
+    2560,  2560,  2560,  2567,  2567,  2567,  2574,  2580,  2585,  2587,
+    2584,  2596,  2594,  2612,  2617,  2610,  2634,  2632,  2649,  2653,
+    2648,  2670,  2676,  2669,  2693,  2697,  2701,  2705,  2711,  2718,
+    2719,  2720,  2723,  2724,  2727,  2728,  2736,  2737,  2743,  2747,
+    2750,  2754,  2758,  2762,  2767,  2771,  2775,  2779,  2785,  2784,
+    2794,  2798,  2802,  2806,  2812,  2817,  2822,  2826,  2830,  2834,
+    2838,  2842,  2846,  2850,  2854,  2858,  2862,  2866,  2870,  2874,
+    2878,  2884,  2889,  2896,  2896,  2900,  2905,  2912,  2916,  2922,
+    2923,  2926,  2931,  2934,  2938,  2944,  2948,  2955,  2954,  2969,
+    2979,  2983,  2988,  2995,  2999,  3003,  3007,  3011,  3015,  3019,
+    3023,  3027,  3034,  3033,  3048,  3047,  3063,  3071,  3080,  3083,
+    3090,  3093,  3097,  3098,  3101,  3105,  3108,  3112,  3115,  3116,
+    3117,  3118,  3121,  3122,  3128,  3129,  3130,  3134,  3140,  3141,
+    3147,  3152,  3151,  3162,  3166,  3172,  3176,  3182,  3186,  3192,
+    3195,  3196,  3199,  3205,  3211,  3212,  3215,  3222,  3221,  3235,
+    3239,  3246,  3251,  3258,  3264,  3265,  3266,  3267,  3268,  3272,
+    3278,  3282,  3288,  3289,  3290,  3294,  3300,  3304,  3308,  3312,
+    3316,  3322,  3326,  3332,  3336,  3340,  3344,  3348,  3352,  3360,
+    3367,  3378,  3379,  3383,  3387,  3386,  3402,  3408,  3426,  3432,
+    3438,  3444,  3451,  3456,  3463,  3467,  3473,  3477,  3483,  3484,
+    3487,  3491,  3497,  3501,  3505,  3509,  3515,  3520,  3525,  3529,
+    3533,  3537,  3541,  3545,  3549,  3553,  3557,  3561,  3565,  3569,
+    3573,  3577,  3582,  3588,  3593,  3598,  3603,  3608,  3615,  3619,
+    3626,  3631,  3630,  3642,  3646,  3652,  3660,  3668,  3676,  3680,
+    3686,  3690,  3696,  3697,  3700,  3705,  3712,  3713,  3716,  3722,
+    3726,  3732,  3737,  3737,  3762,  3763,  3769,  3774,  3780,  3781,
+    3784,  3790,  3795,  3805,  3812,  3813,  3814,  3817,  3818,  3819,
+    3820,  3823,  3824,  3825,  3828,  3829,  3832,  3836,  3842,  3843,
+    3849,  3850,  3853,  3854,  3857,  3860,  3861,  3862,  3865,  3866,
+    3867,  3870,  3877,  3878,  3882
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 1
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "keyword_class", "keyword_module",
+  "keyword_def", "keyword_begin", "keyword_if", "keyword_unless",
+  "keyword_while", "keyword_until", "keyword_for", "keyword_undef",
+  "keyword_rescue", "keyword_ensure", "keyword_end", "keyword_then",
+  "keyword_elsif", "keyword_else", "keyword_case", "keyword_when",
+  "keyword_break", "keyword_next", "keyword_redo", "keyword_retry",
+  "keyword_in", "keyword_do", "keyword_do_cond", "keyword_do_block",
+  "keyword_do_LAMBDA", "keyword_return", "keyword_yield", "keyword_super",
+  "keyword_self", "keyword_nil", "keyword_true", "keyword_false",
+  "keyword_and", "keyword_or", "keyword_not", "modifier_if",
+  "modifier_unless", "modifier_while", "modifier_until", "modifier_rescue",
+  "keyword_alias", "keyword_BEGIN", "keyword_END", "keyword__LINE__",
+  "keyword__FILE__", "keyword__ENCODING__", "tIDENTIFIER", "tFID", "tGVAR",
+  "tIVAR", "tCONSTANT", "tCVAR", "tLABEL_TAG", "tINTEGER", "tFLOAT",
+  "tCHAR", "tXSTRING", "tREGEXP", "tSTRING", "tSTRING_PART", "tSTRING_MID",
+  "tNTH_REF", "tBACK_REF", "tREGEXP_END", "tNUMPARAM", "tUPLUS", "tUMINUS",
+  "tPOW", "tCMP", "tEQ", "tEQQ", "tNEQ", "tGEQ", "tLEQ", "tANDOP", "tOROP",
+  "tMATCH", "tNMATCH", "tDOT2", "tDOT3", "tAREF", "tASET", "tLSHFT",
+  "tRSHFT", "tCOLON2", "tCOLON3", "tOP_ASGN", "tASSOC", "tLPAREN",
+  "tLPAREN_ARG", "tRPAREN", "tLBRACK", "tLBRACE", "tLBRACE_ARG", "tSTAR",
+  "tDSTAR", "tAMPER", "tLAMBDA", "tANDDOT", "tSYMBEG", "tREGEXP_BEG",
+  "tWORDS_BEG", "tSYMBOLS_BEG", "tSTRING_BEG", "tXSTRING_BEG",
+  "tSTRING_DVAR", "tLAMBEG", "tHEREDOC_BEG", "tHEREDOC_END",
+  "tLITERAL_DELIM", "tHD_LITERAL_DELIM", "tHD_STRING_PART",
+  "tHD_STRING_MID", "tLOWEST", "'='", "'?'", "':'", "'>'", "'<'", "'|'",
+  "'^'", "'&'", "'+'", "'-'", "'*'", "'/'", "'%'", "tUMINUS_NUM", "'!'",
+  "'~'", "tLAST_TOKEN", "'{'", "'}'", "'['", "']'", "','", "'`'", "'('",
+  "')'", "';'", "'.'", "'\\n'", "$accept", "program", "$@1",
+  "top_compstmt", "top_stmts", "top_stmt", "@2", "bodystmt", "compstmt",
+  "stmts", "stmt", "$@3", "command_asgn", "command_rhs", "expr",
+  "expr_value", "command_call", "block_command", "cmd_brace_block", "$@4",
+  "command", "mlhs", "mlhs_inner", "mlhs_basic", "mlhs_item", "mlhs_list",
+  "mlhs_post", "mlhs_node", "lhs", "cname", "cpath", "fname", "fsym",
+  "undef_list", "$@5", "op", "reswords", "arg", "aref_args", "arg_rhs",
+  "paren_args", "opt_paren_args", "opt_call_args", "call_args",
+  "command_args", "@6", "block_arg", "opt_block_arg", "comma", "args",
+  "mrhs", "primary", "@7", "@8", "$@9", "$@10", "@11", "@12", "$@13",
+  "$@14", "$@15", "$@16", "$@17", "$@18", "@19", "@20", "@21", "@22",
+  "@23", "@24", "@25", "@26", "primary_value", "then", "do", "if_tail",
+  "opt_else", "for_var", "f_margs", "$@27", "block_args_tail",
+  "opt_block_args_tail", "block_param", "opt_block_param",
+  "block_param_def", "$@28", "opt_bv_decl", "bv_decls", "bvar",
+  "f_larglist", "lambda_body", "do_block", "$@29", "block_call",
+  "method_call", "brace_block", "@30", "@31", "case_body", "cases",
+  "opt_rescue", "exc_list", "exc_var", "opt_ensure", "literal", "string",
+  "string_fragment", "string_rep", "string_interp", "@32", "xstring",
+  "regexp", "heredoc", "heredoc_bodies", "heredoc_body",
+  "heredoc_string_rep", "heredoc_string_interp", "@33", "words", "symbol",
+  "basic_symbol", "sym", "symbols", "numeric", "variable", "var_lhs",
+  "var_ref", "backref", "superclass", "$@34", "f_arglist", "f_label",
+  "f_kw", "f_block_kw", "f_block_kwarg", "f_kwarg", "kwrest_mark",
+  "f_kwrest", "args_tail", "opt_args_tail", "f_args", "f_bad_arg",
+  "f_norm_arg", "f_arg_item", "@35", "f_arg", "f_opt_asgn", "f_opt",
+  "f_block_opt", "f_block_optarg", "f_optarg", "restarg_mark",
+  "f_rest_arg", "blkarg_mark", "f_block_arg", "opt_f_block_arg",
+  "singleton", "$@36", "assoc_list", "assocs", "label_tag", "assoc",
+  "operation", "operation2", "operation3", "dot_or_colon", "call_op",
+  "call_op2", "opt_terms", "opt_nl", "rparen", "trailer", "term", "nl",
+  "terms", "none", YY_NULLPTR
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+   (internal) symbol number NUM (which must be that of a token).  */
+static const yytype_int16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
+     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
+     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
+     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
+     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
+     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
+     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
+     365,   366,   367,   368,   369,   370,   371,   372,   373,    61,
+      63,    58,    62,    60,   124,    94,    38,    43,    45,    42,
+      47,    37,   374,    33,   126,   375,   123,   125,    91,    93,
+      44,    96,    40,    41,    59,    46,    10
+};
+# endif
+
+#define YYPACT_NINF (-829)
+
+#define yypact_value_is_default(Yyn) \
+  ((Yyn) == YYPACT_NINF)
+
+#define YYTABLE_NINF (-595)
+
+#define yytable_value_is_error(Yyn) \
+  ((Yyn) == YYTABLE_NINF)
+
+  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+     STATE-NUM.  */
+static const yytype_int16 yypact[] =
+{
+    -829,   164,  2491,  -829,  7022,  8994,  9330,  5100,  -829,  8646,
+    8646,  -829,  -829,  9106,  6520,  4956,  7370,  7370,  -829,  -829,
+    7370,  2735,  5870,  -829,  -829,  -829,  -829,   -39,  6520,  -829,
+      36,  -829,  -829,  -829,  5240,  5380,  -829,  -829,  5520,  -829,
+    -829,  -829,  -829,  -829,  -829,  -829,    20,  8762,  8762,   129,
+    4227,  1481,  7602,  7950,  6798,  -829,  6242,   614,   927,  1024,
+    1126,   839,  -829,   410,  8878,  8762,  -829,   852,  -829,  1251,
+    -829,   448,  -829,  -829,   166,   171,  -829,    80,  9218,  -829,
+     198, 11318,   299,   402,    21,    59,  -829,   354,  -829,  -829,
+    -829,  -829,  -829,  -829,  -829,  -829,  -829,   203,   165,  -829,
+     340,   137,  -829,  -829,  -829,  -829,  -829,   159,   159,   177,
+      72,   552,  -829,  8646,    99,  4344,   607,  -829,   200,  -829,
+     494,  -829,  -829,   137,  -829,  -829,  -829,  -829,  -829,  -829,
+    -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,
+    -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,
+    -829,  -829,    33,    44,    47,   101,  -829,  -829,  -829,  -829,
+    -829,  -829,   170,   218,   219,   227,  -829,   229,  -829,  -829,
+    -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,
+    -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,
+    -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,
+    -829,  -829,  -829,   240,  3417,   270,   448,    83,   225,   526,
+      61,   247,    86,    83,  8646,  8646,   539,   306,  -829,  -829,
+     609,   329,    95,   110,  -829,  -829,  -829,  -829,  -829,  -829,
+    -829,  -829,  -829,  6381,  -829,  -829,   253,  -829,  -829,  -829,
+    -829,  -829,  -829,   852,  -829,   264,  -829,   386,  -829,  -829,
+     852,  2601,  8762,  8762,  8762,  8762,  -829, 11297,  -829,  -829,
+     271,   361,   271,  -829,  -829,  -829,  7138,  -829,  -829,  -829,
+    7370,  -829,  -829,  -829,  4956,  8646,  -829,  -829,   286,  4461,
+    -829,   796,   355,   398,  7254,  4227,   302,   852,  1251,   852,
+     323,  -829,  7254,   852,   325,  1517,  1517,  -829, 11297,   316,
+    1517,  -829,   421,  9442,   370,   798,   826,   859,  1597,  -829,
+    -829,  -829,  -829,  1166,  -829,  -829,  -829,  -829,  -829,  -829,
+     679,   749,  -829,  -829,  1186,  -829,  1195,  -829,  1257,  -829,
+     860,   444,   446,  -829,  -829,  -829,  -829,  4722,  8646,  8646,
+    8646,  8646,  7254,  8646,  8646,  -829,  -829,  8066,  -829,  4227,
+    6910,   392,  8066,  8762,  8762,  8762,  8762,  8762,  8762,  8762,
+    8762,  8762,  8762,  8762,  8762,  8762,  8762,  8762,  8762,  8762,
+    8762,  8762,  8762,  8762,  8762,  8762,  8762,  8762,  8762,  9714,
+    -829,  7370,  -829,  9798,  -829,  -829, 10974,  -829,  -829,  -829,
+    -829,  8878,  8878,  -829,   428,  -829,   448,  -829,   961,  -829,
+    -829,  -829,  -829,  -829,  9882,  7370,  9966,  3417,  8646,  -829,
+    -829,  -829,  -829,   522,   528,   149,  -829,  3561,   533,  8762,
+   10050,  7370, 10134,  8762,  8762,  3849,   126,   126,   113, 10218,
+    7370, 10302,  -829,   501,  -829,  4461,   386,  -829,  -829,  8182,
+     542,  -829,   679,  8762, 11318, 11318, 11318,  8762,   476,  -829,
+    7486,  -829,  8762,  -829,  7718,   852,   425,   852,   271,   271,
+    -829,  -829,   745,   431,  -829,  -829,  6520,  3966,   443, 10050,
+   10134,  8762,  1251,   852,  -829,  -829,  4839,   445,  1251,  -829,
+    -829,  7834,  -829,   852,  7950,  -829,  -829,  -829,   961,    80,
+    9442,  -829,  9442, 10386,  7370, 10470,    30,  -829,  -829,  -829,
+    -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  1719,
+    -829,  8762,  -829,   451,   554,   472,  -829,  -829,  -829,  -829,
+    -829,   479,  8762,  -829,   497,   596,   511,   608,  -829,  -829,
+    1283,  4461,   679,  -829,  -829,  -829,  -829,  -829,  -829,  -829,
+    8762,  8762,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,
+     153,  8762,  -829, 11121,   271,  -829,   852,  9442,   532,  -829,
+    -829,  -829,   570,   572,  2302,  -829,  -829,   976,   180,   355,
+    2331,  2331,  2331,  2331,  1479,  1479, 11455, 11395,  2331,  2331,
+   11378, 11378,   671,   671, 11061,  1479,  1479,  1462,  1462,  1490,
+     175,   175,   355,   355,   355,  2869,  5986,  3137,  6102,  -829,
+     159,  -829,   550,   437,  -829,   563,  -829,  -829,  5870,  -829,
+    -829,  2061,   153,   153,  -829, 11044,  -829,  -829,  -829,  -829,
+    -829,   852,  8646,  3417,   736,   813,  -829,   159,   560,   159,
+     699,   745,  1650,  6659,  -829,  8298,   706,  -829,   690,  -829,
+    5636,  5753,   605,   268,   276,   706,  -829,  -829,  -829,  -829,
+      79,    88,   613,   121,   140,  8646,  6520,   616,   740, 11318,
+     450,  -829,   679, 11318, 11318,   679,  8762, 11297,  -829,   271,
+   11318,  -829,  -829,  -829,  -829,  7486,  7718,  -829,  -829,  -829,
+     623,  -829,  -829,   136,  1251,   852,  1517,   392,  -829,   736,
+     813,   626,   959,  1023,  -829,  -829,  1123,   622,    77, 11318,
+     768,  -829,  -829,  -829,   201,  -829,  1719,  -829, 11318,  1719,
+    -829,  -829,  1907,  -829,  -829,  -829,   637,  -829,   355,   355,
+    -829,  1719,  3417,  -829,  -829, 11140,  8414,  -829,  -829,  9442,
+    7254,  8878,  8762, 10554,  7370, 10638,    70,  8878,  8878,  -829,
+     428,   672,  8878,  8878,  -829,   428,    59,   166,  3417,  4461,
+     153,  -829,   852,   762,  -829,  -829,  -829,  1826,  3417,   852,
+    -829, 11121,  -829,   689,  -829,  4110,   774,  -829,  8646,   779,
+    -829,  8762,  8762,   358,  8762,  8762,   800,  4605,  4605,   156,
+     126,  -829,  -829,  -829,  8530,  3705,   679, 11318,  -829,   271,
+    -829,  -829,  -829,   192,  -829,   104,   852,   676,   674,   678,
+    3417,  4461,  -829,   766,  -829,   472,  -829,  -829,  -829,   684,
+     686,   687,  -829,   691,   766,   687,  -829,  -829,   622,   622,
+    9554,  -829,   694,   472,   695,  9554,  -829,   698,   701,  -829,
+     835,  8762, 11209,  -829,  -829, 11318,  3003,  3271,   712,   408,
+     432,  8762,  8762,  -829,  -829,  -829,  -829,  -829,  8878,  -829,
+    -829,  -829,  -829,  -829,  -829,  -829,   840,   722,  4461,  3417,
+    -829,  -829,   852,   852,   845,  -829,  1650,  9666,    83,  -829,
+    -829,  4605,  -829,  -829,    83,  -829,  8762,  -829,   855,   856,
+    -829, 11318,   193,  7718,  -829,   733,  -829,  1530,  -829,   680,
+     868,   753,  -829,  1719,  -829,  1907,  -829,  1907,  -829,  1907,
+    -829,  -829,   769,   771,   837,   995,   768,  -829,  -829,  1282,
+    -829,   995,  1719,  -829,  1907,  -829,  -829, 11228,   439, 11318,
+   11318,  -829,  -829,  -829,  -829,   761,   896,  -829,  -829,  -829,
+    3417,   862,  -829,  1028,   826,   859,  3417,  -829,  3561,  -829,
+    -829,  4605,  -829,  -829,  -829,  1585,  1585,   547,  -829,    22,
+    -829,  -829,  -829,  -829,   687,   778,   687,   687,  -829,  -829,
+    -829, 10722,  -829,   472,   768,  -829,  -829,   780,   792,   793,
+    -829,   799,   793,  -829,  -829,   913,   961, 10806,  7370, 10890,
+     528,   690,   935,   812,   812,  1585,   823,   680,  -829,  -829,
+    1907,  -829,  -829,  -829,   824,   828,  -829,  1719,  -829,  1907,
+    -829,  1907,  -829,  1907,  -829,  -829,  -829,   736,   813,   834,
+     357,   579,  -829,  -829,  -829,  1585,   812,  1585,  -829,   687,
+     793,   842,   793,   793,   192,   812,  -829,  -829,  1907,  -829,
+    -829,  -829,   793,  -829
+};
+
+  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+     Performed when YYTABLE does not specify something else to do.  Zero
+     means the default is an error.  */
+static const yytype_int16 yydefact[] =
+{
+       2,     0,     0,     1,     0,     0,     0,     0,   276,     0,
+       0,   300,   303,     0,     0,   580,   324,   325,   326,   327,
+     288,   253,   400,   475,   474,   476,   477,   582,     0,    10,
+       0,   479,   478,   480,   466,   275,   468,   467,   470,   469,
+     462,   463,   424,   425,   481,   482,   274,     0,     0,     0,
+       0,   278,   594,   594,    80,   295,     0,     0,     0,     0,
+       0,     0,   439,     0,     0,     0,     3,   580,     6,     9,
+      27,    32,    44,    52,    51,     0,    68,     0,    72,    82,
+       0,    49,   232,     0,    53,   293,   267,   268,   422,   269,
+     270,   271,   420,   419,   451,   421,   418,   473,     0,   272,
+     273,   253,     5,     8,   324,   325,   288,   594,   400,     0,
+     105,   106,   274,     0,     0,     0,     0,   108,   483,   328,
+       0,   473,   273,     0,   316,   160,   170,   161,   157,   186,
+     187,   188,   189,   168,   183,   176,   166,   165,   181,   164,
+     163,   159,   184,   158,   171,   175,   177,   169,   162,   178,
+     185,   180,   179,   172,   182,   167,   156,   174,   173,   155,
+     153,   154,   150,   151,   152,   110,   112,   111,   145,   146,
+     141,   123,   124,   125,   132,   129,   131,   126,   127,   147,
+     148,   133,   134,   138,   142,   128,   130,   120,   121,   122,
+     135,   136,   137,   139,   140,   143,   144,   149,   552,   318,
+     113,   114,   551,     0,     0,     0,    50,     0,     0,     0,
+     473,     0,   273,     0,     0,     0,   104,     0,   339,   338,
+       0,     0,   473,   273,   179,   172,   182,   167,   150,   151,
+     152,   110,   111,     0,   115,   117,    20,   116,   442,   447,
+     446,   588,   591,   580,   590,     0,   444,     0,   592,   589,
+     581,   564,     0,     0,     0,     0,   248,   260,    66,   252,
+     594,   422,   594,   556,    67,    65,   594,   242,   289,    64,
+       0,   241,   399,    63,   580,     0,   583,    18,     0,     0,
+     209,     0,   210,   285,     0,     0,     0,   580,    15,   580,
+      70,    14,     0,   580,     0,   585,   585,   233,     0,     0,
+     585,   554,     0,     0,    78,     0,    88,    95,   522,   456,
+     455,   457,   458,     0,   454,   453,   437,   431,   430,   433,
+       0,     0,   428,   449,     0,   460,     0,   426,     0,   435,
+       0,   464,   465,    48,   224,   225,     4,   581,     0,     0,
+       0,     0,     0,     0,     0,   387,   389,     0,    84,     0,
+      76,    73,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     577,   594,   576,     0,   579,   578,     0,   404,   402,   294,
+     423,     0,     0,   393,    57,   292,   313,   105,   106,   107,
+     464,   465,   484,   311,     0,   594,     0,     0,     0,   319,
+     575,   574,   321,     0,   594,   285,   330,     0,   329,     0,
+       0,   594,     0,     0,     0,     0,     0,     0,   285,     0,
+     594,     0,   308,     0,   118,     0,     0,   443,   445,     0,
+       0,   593,   558,     0,   261,   563,   255,     0,   258,   249,
+       0,   257,     0,   250,     0,   580,     0,   580,   594,   594,
+     243,   254,   580,     0,   291,    47,     0,     0,     0,     0,
+       0,     0,    17,   580,   283,    13,   581,    69,   279,   282,
+     286,   587,   234,   586,   587,   236,   287,   555,    94,    86,
+       0,    81,     0,     0,   594,     0,   529,   525,   524,   523,
+     526,   527,   498,   531,   543,   499,   547,   546,   542,   522,
+     296,   491,   496,   594,   501,   594,   521,   384,   528,   530,
+     533,   507,     0,   540,   507,   545,   507,     0,   505,   459,
+       0,     0,   434,   440,   438,   429,   450,   461,   427,   436,
+       0,     0,     7,    21,    22,    23,    24,    25,    45,    46,
+     594,     0,    28,    30,     0,    31,   580,     0,    74,    85,
+      43,    33,    41,     0,   237,   190,    29,     0,   273,   206,
+     214,   219,   220,   221,   216,   218,   228,   229,   222,   223,
+     199,   200,   226,   227,   582,   215,   217,   211,   212,   213,
+     201,   202,   203,   204,   205,   567,   572,   568,   573,   398,
+     253,   396,     0,   567,   569,   568,   570,   397,   594,   567,
+     568,   253,   594,   594,    34,   237,   191,    40,   198,    55,
+      58,     0,     0,     0,   105,   106,   109,     0,     0,   594,
+       0,   580,   522,     0,   277,   594,   594,   410,   594,   331,
+     571,   284,     0,   567,   568,   594,   333,   301,   332,   304,
+     571,   284,     0,   567,   568,     0,     0,     0,     0,   260,
+       0,   307,   559,   561,   560,     0,     0,   262,   256,   594,
+     562,   557,   240,   239,   244,   245,   247,   290,   584,    19,
+       0,    26,   197,    71,    16,   580,   585,    87,    79,    91,
+      93,     0,    90,    92,   489,   535,     0,   582,     0,   490,
+       0,   503,   550,   500,     0,   504,     0,   514,   536,     0,
+     517,   544,     0,   519,   548,   452,     0,   441,   207,   208,
+     375,   373,     0,   372,   371,   266,     0,    83,    77,     0,
+       0,     0,     0,     0,   594,     0,     0,     0,     0,   395,
+      61,   401,     0,     0,   394,    59,   390,    54,     0,     0,
+     594,   314,     0,     0,   401,   317,   553,   522,     0,     0,
+     322,   411,   412,   594,   413,     0,   594,   336,     0,     0,
+     334,     0,     0,   401,     0,     0,     0,     0,     0,   401,
+       0,   119,   448,   306,     0,     0,   259,   263,   251,   594,
+      11,   280,   235,    89,   529,   347,   580,   340,     0,   377,
+       0,     0,   297,     0,   497,   594,   549,   506,   534,   507,
+     507,   507,   541,   507,   529,   507,   432,   370,   582,   582,
+     493,   494,   594,   594,   355,     0,   538,   355,   355,   353,
+       0,     0,   264,    75,    42,   238,   567,   568,     0,   567,
+     568,     0,     0,    39,   195,    38,   196,    62,     0,    36,
+     193,    37,   194,    60,   391,   392,     0,     0,     0,     0,
+     485,   312,   580,   580,     0,   488,   522,     0,     0,   415,
+     337,     0,    12,   417,     0,   298,     0,   299,     0,     0,
+     309,   262,   594,   246,   348,   345,   532,     0,   383,     0,
+       0,     0,   502,     0,   510,     0,   512,     0,   518,     0,
+     515,   520,     0,     0,     0,   492,     0,   351,   352,   355,
+     363,   537,     0,   366,     0,   368,   388,   265,   401,   231,
+     230,    35,   192,   405,   403,     0,     0,   487,   486,   320,
+       0,     0,   414,     0,    96,   103,     0,   416,     0,   302,
+     305,     0,   407,   408,   406,     0,     0,   343,   381,   582,
+     379,   382,   386,   385,   507,   507,   507,   507,   376,   374,
+     285,     0,   495,   594,     0,   354,   361,   355,   355,   355,
+     539,   355,   355,    56,   315,     0,   102,     0,   594,     0,
+     594,   594,     0,   349,   346,     0,   341,     0,   378,   511,
+       0,   508,   513,   516,   571,   284,   350,     0,   358,     0,
+     360,     0,   367,     0,   364,   369,   323,    99,   101,     0,
+     567,   568,   409,   335,   310,     0,   344,     0,   380,   507,
+     355,   355,   355,   355,    97,   342,   509,   359,     0,   356,
+     362,   365,   355,   357
+};
+
+  /* YYPGOTO[NTERM-NUM].  */
+static const yytype_int16 yypgoto[] =
+{
+    -829,  -829,  -829,   510,  -829,    32,  -829,  -214,   182,  -829,
+      28,  -829,  -155,  -302,   867,     1,   -16,  -829,  -536,  -829,
+     131,   971,  -170,     4,   -69,  -266,  -431,   -15,  1295,   -48,
+     981,    19,     5,  -829,  -829,    24,  -829,   653,  -829,   413,
+      75,   -58,  -352,    54,    13,  -829,  -390,  -235,   -11,    39,
+    -303,    89,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,
+    -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,  -829,
+    -829,  -829,     8,  -206,  -382,     7,  -568,  -829,  -829,  -829,
+     272,   538,  -829,  -512,  -829,  -829,   -78,  -829,     2,  -829,
+    -829,   255,  -829,  -829,  -829,   -65,  -829,  -829,  -430,  -829,
+      14,  -829,  -829,  -829,  -829,  -829,   154,    58,  -196,  -829,
+    -829,  -829,  -829,  -377,  -257,  -829,   787,  -829,  -829,  -829,
+      -6,  -829,  -829,  -829,  1461,  1552,  1026,  1065,  -829,  -829,
+     173,   314,   343,   141,  -829,  -829,  -829,   524,  -306,   246,
+    -307,  -801,  -716,  -519,  -829,   474,  -664,  -627,  -828,   142,
+     346,  -829,   236,  -829,   517,  -439,  -829,  -829,  -829,    92,
+     785,  -411,   505,  -339,  -829,  -829,   -80,  -829,    26,   -22,
+    -152,  -254,   788,   -12,   -33,    -2
+};
+
+  /* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int16 yydefgoto[] =
+{
+      -1,     1,     2,    66,    67,    68,   278,   413,   414,   287,
+     288,   466,    70,   561,    71,   207,    72,    73,   620,   750,
+      74,    75,   289,    76,    77,    78,   491,    79,   208,   117,
+     118,   234,   235,   236,   656,   598,   201,    81,   294,   565,
+     599,   268,   456,   457,   269,   270,   259,   449,   484,   458,
+     555,    82,   204,   292,   685,   293,   308,   698,   214,   777,
+     215,   778,   655,   941,   623,   621,   859,   407,   409,   632,
+     633,   866,   281,   417,   647,   769,   770,   221,   796,   945,
+     965,   910,   818,   722,   723,   819,   798,   949,   950,   510,
+     802,   346,   550,    84,    85,   395,   613,   612,   440,   944,
+     636,   763,   868,   872,    86,    87,    88,   321,   322,   531,
+      89,    90,    91,   532,   244,   245,   246,   435,    92,    93,
+      94,   315,    95,    96,   210,   211,    99,   212,   403,   622,
+     758,   511,   512,   821,   822,   513,   514,   515,   807,   707,
+     759,   518,   519,   520,   696,   521,   522,   523,   826,   827,
+     524,   525,   526,   527,   528,   701,   203,   408,   299,   459,
+     443,   263,   123,   627,   601,   412,   406,   386,   463,   799,
+     464,   482,   248,   249,   250,   291
+};
+
+  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+     positive, shift that token.  If negative, reduce the rule whose
+     number is the opposite.  If YYTABLE_NINF, syntax error.  */
+static const yytype_int16 yytable[] =
+{
+     102,   517,   516,   383,   385,   275,   658,   425,   237,   351,
+      83,   213,    83,   120,   120,   276,   243,   209,   209,   271,
+     389,   220,   237,   209,   209,   209,   199,   453,   209,   602,
+      69,   200,    69,   277,   337,   273,   103,   490,   200,   304,
+     600,   247,   485,   671,   608,   649,   487,   611,   333,   566,
+     297,   301,   200,   628,   290,   260,   260,   825,    83,   260,
+     668,   688,   305,   533,   668,   662,   399,   629,   766,   642,
+     258,   264,   209,   671,   265,   314,   705,   776,   652,   885,
+     200,   600,   812,   608,   970,   387,   305,   694,   951,   614,
+     617,   295,   629,   336,   119,   119,   267,   272,  -564,   416,
+     748,   749,   119,   274,   -99,   271,   800,   242,   262,   262,
+     384,  -472,   262,  -101,   394,   473,   324,   326,   328,   330,
+     -96,   209,  -475,    83,   380,   535,   728,   841,   535,   422,
+     535,   629,   535,  -474,   535,  -103,  -476,   477,  -102,  -104,
+     431,   479,   691,   119,   296,   300,   -98,   256,   256,   695,
+     397,   256,  -471,   646,   398,   794,   629,   497,   498,   499,
+     500,  -466,   987,   387,     3,  -100,   382,   119,   242,   970,
+     261,   261,   279,   501,   261,  -466,   393,   424,  -475,   556,
+     -96,   -97,   267,   272,   283,   533,   951,   808,   801,  -474,
+    -477,   842,  -476,   630,   345,   388,   238,   560,   393,   239,
+     240,   470,   697,   516,   847,  -103,   261,   261,  -564,   853,
+    -466,   765,    83,   439,  -564,   426,   427,  -466,  -401,   -91,
+     348,  -567,   209,   209,   453,   495,   490,   241,   -93,   242,
+    -568,   986,   286,   720,   489,   -88,   560,   560,   858,   238,
+     471,   390,   239,   240,   884,   825,  -477,   353,   825,   450,
+     -95,   454,   314,   -94,   476,   -69,   391,   200,   451,  -479,
+     451,   -90,   483,   483,   460,   671,   812,   483,  -102,   436,
+     241,   392,   242,   388,   209,   717,   -83,   721,   209,   266,
+     -92,  -401,   209,   209,   481,   668,   668,    83,   786,   290,
+     347,   490,    83,    83,  -471,  -401,   -89,   286,   833,  -103,
+      83,   266,   506,   672,   376,   377,   378,  -478,  -480,   260,
+     677,   305,   472,   475,   942,  -479,  -466,   352,  -470,   274,
+     478,   683,   -96,   402,   461,   415,   516,   507,  -401,   410,
+    -401,   552,   762,   825,   535,   558,   562,  -401,   423,   543,
+     544,   545,   546,   -88,   419,    83,   209,   209,   209,   209,
+      83,   209,   209,   290,   432,   209,   626,    83,   305,   774,
+     567,   428,   262,  -478,  -480,    69,   892,   775,   808,   542,
+     547,   530,  -466,   -98,  -470,   562,   562,   437,   808,   460,
+     239,   240,   838,   907,   908,   411,   554,   -98,  -328,   209,
+     808,   554,   119,   434,   600,  -100,   608,   256,   880,   567,
+     567,   256,  -328,   460,   727,   717,   439,   606,   533,   753,
+     606,   448,   637,   209,    42,    83,   209,    43,   442,   460,
+     261,   687,   467,   489,   261,    83,   665,   353,   460,   209,
+     606,   392,   792,    83,   788,   843,   276,  -328,   209,   119,
+     849,   851,   -68,    83,  -328,   474,   606,   675,   676,   876,
+     863,   516,   943,   486,   785,   606,   451,   451,   607,  -103,
+     237,   468,    60,   490,   480,   102,   416,   286,   331,   332,
+     -98,   679,   671,   -98,   -98,    83,   488,   -97,   660,   756,
+     -95,   607,   808,   674,    83,   343,   344,   735,   489,   471,
+     200,   379,   460,   668,   606,    69,   808,   607,   305,   742,
+     305,   -98,   209,   -98,   684,   380,   607,   101,   830,   101,
+     492,   702,   256,   702,   101,   101,   540,  -102,   541,   606,
+     101,   101,   101,   743,   996,   101,   619,   -98,   742,   717,
+     848,   286,   559,   791,   856,   261,   256,   634,   -94,    83,
+     381,   635,   669,   726,   864,   607,   921,   382,   724,   639,
+     744,  -100,   256,   746,   788,   101,   -98,   661,   -97,   261,
+     516,   256,   736,   238,   529,   305,   239,   240,   673,   101,
+     607,   744,   276,   686,   678,   261,   560,   -90,  -565,   119,
+     681,   119,   560,   404,   261,   -83,   890,   560,   560,  -582,
+     448,   700,  -582,  -582,   241,  -100,   242,   380,   794,   638,
+     497,   498,   499,   500,   261,   703,   271,   645,   261,   271,
+     724,   724,   704,   740,   730,   420,   501,   657,   101,   706,
+     101,   745,   242,   752,   747,   256,  1009,   271,  -274,   380,
+     209,    83,   405,   764,   767,   261,   767,   709,   261,   382,
+     629,  -470,  -274,   767,   886,   926,   119,   711,   261,   784,
+     237,   712,   760,   483,   743,  -470,   780,   200,   454,   714,
+     489,   781,   936,   209,   421,   400,   401,   451,   938,   257,
+     257,   382,   729,   257,   554,   739,   316,  -274,   317,   318,
+     200,   854,  -100,   267,  -274,   276,   267,   985,  -565,   741,
+    -470,   731,  -100,   560,  -565,  -100,  -100,  -470,   429,   754,
+     280,   282,   739,   -92,   267,   257,   298,   768,   765,   101,
+     927,   928,   380,   716,   755,   562,   975,   334,   335,   101,
+     101,   562,   845,  -100,   765,  -100,   562,   562,   319,   320,
+      83,   948,   460,   497,   498,   499,   500,   305,    83,   567,
+     902,   903,   209,   353,   773,   567,   209,   430,   724,   501,
+     567,   567,   779,   782,   382,   783,    83,    83,   834,   606,
+     790,   869,  -571,   848,   873,   793,    83,   789,   242,   874,
+     710,   101,   713,    83,   816,   101,   209,   861,   883,   101,
+     101,   867,   343,   344,   101,    83,    83,   451,   871,   101,
+     101,   -97,   238,    83,   875,   239,   240,   101,   374,   375,
+     376,   377,   378,   702,   616,   618,   276,   276,    83,    83,
+     607,   534,   -89,   317,   318,   877,   887,   888,   119,   803,
+     702,   702,   889,   694,   893,  -571,   895,   897,   905,   261,
+     261,   899,   562,   911,   906,   909,   616,   618,   912,  -571,
+     502,   914,   101,   101,   101,   101,   101,   101,   101,   101,
+     916,   918,   101,   979,   101,   923,   567,   101,   238,   924,
+     929,   239,   240,   319,   320,   256,    83,    83,   505,   506,
+     939,   940,  -571,   946,  -571,   933,   206,   206,  -567,    83,
+     767,  -571,   206,   952,   682,   469,   101,   493,   261,   241,
+     953,   242,   960,   958,   507,   959,   101,   101,   973,   380,
+     329,   380,  -284,   317,   318,   444,   445,   446,   334,   119,
+     101,   974,   101,   101,   119,  -473,  -284,   976,   990,   257,
+     997,   539,   101,   257,   317,   318,   101,   988,  1006,  -473,
+     101,   857,   999,  1001,   421,   101,   494,   276,    83,  1003,
+     101,   382,   810,   382,    83,   813,    83,   870,  -273,    83,
+    1014,  -284,  1015,   319,   320,  -568,   119,   828,  -284,   878,
+     879,   702,  -273,  1017,  -473,   238,  -567,   882,   239,   240,
+    -568,  -473,   101,  1024,   319,   320,   460,   680,   637,   767,
+     396,   101,  1028,   891,   218,  -567,   209,   124,  1013,  1018,
+     323,   317,   318,   817,  1012,   418,   241,  -273,   242,   101,
+     553,   418,   855,   606,  -273,   564,   569,   570,   571,   572,
+     573,   574,   575,   576,   577,   578,   579,   580,   581,   582,
+     583,   584,   585,   586,   587,   588,   589,   590,   591,   592,
+     593,   594,   438,   202,   257,   820,   101,   261,   441,   930,
+     925,   319,   320,   804,   615,   615,   452,   962,  -567,  -568,
+    -285,   967,   809,   937,   607,   894,   896,   898,   257,   900,
+       0,   901,  -567,     0,  -285,   733,     0,   100,     0,   100,
+     122,   122,   615,     0,   257,     0,   615,   615,   223,   380,
+       0,   206,   206,   257,   961,     0,     0,   325,   317,   318,
+       0,     0,   659,     0,     0,  -567,   663,  -567,   380,  -285,
+     664,  -567,     0,   667,  -567,   670,  -285,   298,     0,   256,
+       0,     0,  -568,     0,   734,   100,     0,   977,   980,   307,
+     981,   382,     0,   982,   615,   441,  -568,   101,   101,   955,
+       0,   380,   261,   405,   667,     0,     0,   298,   319,   320,
+     382,   462,   465,   307,     0,   968,     0,   257,   971,     0,
+     844,   846,     0,     0,     0,   850,   852,     0,     0,  -568,
+     101,  -568,     0,     0,   699,  -568,   978,     0,  -568,     0,
+     797,     0,     0,   382,   794,   708,   497,   498,   499,   500,
+     100,     0,     0,   811,   844,   846,   815,   850,   852,   327,
+     317,   318,   501,   718,   719,   824,     0,     0,     0,     0,
+     989,   991,   992,   993,   725,   206,   206,   206,   206,     0,
+     548,   549,     0,     0,   648,   648,   503,   806,     0,     0,
+     820,   806,   795,   820,   805,     0,   820,   101,   820,   529,
+     317,   318,     0,  1021,     0,   101,   101,     0,   829,   101,
+     319,   320,   101,   101,     0,   823,     0,   101,   101,   536,
+     317,   318,     0,   101,   101,     0,     0,     0,   537,   317,
+     318,   922,     0,   101,   441,  1026,     0,     0,     0,   100,
+     101,   441,     0,   101,     0,   631,     0,     0,   820,     0,
+     319,   320,   101,   101,     0,     0,     0,     0,   761,   922,
+     101,   338,   339,   340,   341,   342,     0,    80,     0,    80,
+     319,   320,     0,     0,     0,   101,   101,     0,   219,   319,
+     320,   820,     0,   820,     0,   820,     0,   820,     0,   787,
+     538,   317,   318,     0,     0,     0,     0,     0,   667,   298,
+       0,     0,     0,   496,     0,   497,   498,   499,   500,     0,
+       0,     0,   820,     0,   100,    80,   715,   317,   318,   100,
+     100,   501,     0,   101,   502,     0,     0,   100,     0,     0,
+       0,     0,     0,   101,   101,   913,   915,   954,   307,   956,
+       0,   319,   320,   957,     0,   503,   101,     0,     0,   832,
+       0,   504,   505,   506,   615,   835,   969,   257,   972,     0,
+     615,   615,     0,     0,     0,   615,   615,   319,   320,     0,
+       0,     0,   100,     0,     0,     0,     0,   100,   507,   751,
+      80,   508,     0,     0,   100,   307,     0,   568,     0,   983,
+     984,     0,   964,   806,   615,   615,   829,   615,   615,   829,
+     963,   829,     0,   823,     0,   101,   823,   881,   823,     0,
+       0,   101,     0,   101,     0,     0,   101,   966,   418,     0,
+       0,     0,     0,     0,     0,     0,   568,   568,     0,  1016,
+       0,     0,     0,    97,  1019,    97,   121,   121,   121,     0,
+       0,  1020,   100,  1022,   222,     0,     0,  1023,     0,     0,
+       0,   829,   100,   101,   917,     0,     0,     0,   823,   206,
+     100,  1025,     0,     0,   919,   920,     0,     0,     0,    80,
+     100,   615,  1032,     0,     0,   998,  1000,  1002,     0,  1004,
+    1005,    97,     0,     0,   829,   306,   829,     0,   829,     0,
+     829,   823,   206,   823,     0,   823,     0,   823,     0,   615,
+       0,     0,   100,     0,   353,     0,   298,     0,     0,   306,
+     860,   100,     0,     0,     0,   829,     0,   865,     0,   366,
+     367,   353,   823,     0,    98,   307,    98,   307,  1027,  1029,
+    1030,  1031,   353,     0,     0,     0,   366,   367,   648,     0,
+    1033,     0,     0,     0,    80,     0,    97,   366,   367,    80,
+      80,   794,     0,   497,   498,   499,   500,    80,   373,   374,
+     375,   376,   377,   378,  -281,     0,   100,  -281,  -281,   501,
+       0,     0,    98,   371,   372,   373,   374,   375,   376,   377,
+     378,     0,     0,     0,     0,     0,     0,   374,   375,   376,
+     377,   378,   307,   503,  -281,  -281,     0,  -281,     0,   947,
+     238,   257,    80,   239,   240,   206,   794,    80,   497,   498,
+     499,   500,     0,     0,    80,     0,     0,   563,   496,     0,
+     497,   498,   499,   500,   501,     0,   418,   448,     0,     0,
+       0,   241,   418,   242,     0,    97,   501,    98,     0,   502,
+       0,     0,     0,     0,     0,     0,     0,     0,   503,     0,
+       0,     0,     0,     0,     0,     0,   563,   563,   100,     0,
+     503,     0,     0,     0,     0,     0,   504,   505,   506,     0,
+       0,   496,    80,   497,   498,   499,   500,     0,     0,     0,
+       0,     0,    80,     0,     0,     0,     0,     0,     0,   501,
+      80,     0,   502,   507,     0,     0,   508,     0,     0,     0,
+      80,     0,     0,     0,     0,     0,     0,     0,     0,   509,
+      97,     0,     0,   503,     0,    97,    97,     0,     0,   504,
+     505,   506,     0,    97,     0,     0,    98,     0,     0,     0,
+       0,     0,    80,     0,   306,     0,     0,     0,     0,     0,
+     496,    80,   497,   498,   499,   500,   507,     0,     0,   508,
+       0,     0,     0,     0,     0,     0,     0,   100,   501,     0,
+       0,   502,   757,     0,   307,   100,   568,     0,    97,     0,
+       0,     0,   568,    97,     0,     0,     0,   568,   568,     0,
+      97,   306,   503,   100,   100,     0,     0,     0,   504,   505,
+     506,     0,     0,   100,     0,     0,    80,     0,     0,     0,
+     100,    98,     0,     0,     0,     0,    98,    98,     0,     0,
+       0,     0,   100,   100,    98,   507,     0,     0,   508,     0,
+     100,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   100,   100,     0,    97,     0,
+       0,     0,     0,     0,     0,     0,     0,   496,    97,   497,
+     498,   499,   500,     0,     0,   122,    97,     0,     0,    98,
+     122,     0,     0,     0,    98,   501,    97,     0,   502,     0,
+       0,    98,     0,     0,    98,     0,     0,     0,     0,     0,
+     862,     0,     0,   568,     0,     0,     0,     0,    80,   503,
+       0,     0,     0,   100,   100,   504,   505,   506,    97,     0,
+       0,     0,   935,     0,     0,     0,   100,    97,     0,     0,
+       0,     0,     0,    98,    98,     0,     0,     0,     0,     0,
+       0,   306,   507,   306,     0,   508,     0,     0,   814,    98,
+     497,   498,   499,   500,     0,     0,     0,     0,     0,    98,
+       0,     0,     0,     0,     0,     0,   501,    98,     0,   502,
+       0,     0,     0,     0,     0,     0,     0,    98,     0,     0,
+       0,     0,    97,     0,     0,   100,     0,     0,     0,     0,
+     503,   100,     0,   100,     0,     0,   100,   505,   506,     0,
+       0,     0,     0,     0,     0,     0,     0,    80,   306,    98,
+       0,     0,     0,     0,     0,    80,   563,     0,    98,     0,
+       0,     0,   563,   507,     0,     0,     0,   563,   563,     0,
+       0,     0,     0,    80,    80,     0,     0,     0,     0,     0,
+       0,     0,     0,    80,     0,     0,     0,     0,     0,     0,
+      80,  -594,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    80,    80,  -594,  -594,  -594,  -594,  -594,  -594,
+      80,  -594,     0,    98,    97,     0,     0,  -594,  -594,     0,
+       0,     0,     0,     0,     0,    80,    80,     0,  -594,  -594,
+       0,  -594,  -594,  -594,  -594,  -594,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   563,     0,     0,     0,     0,     0,     0,
+    -594,     0,     0,    80,    80,     0,     0,     0,     0,     0,
+       0,     0,   932,     0,  -594,     0,    80,     0,     0,     0,
+       0,     0,     0,     0,  -594,    98,     0,  -594,  -594,     0,
+       0,     0,     0,    97,     0,     0,     0,     0,     0,     0,
+     306,    97,     0,     0,     0,     0,     0,  -594,  -594,     0,
+       0,     0,     0,   266,  -594,  -594,  -594,  -594,     0,    97,
+      97,     0,     0,     0,     0,     0,     0,     0,     0,    97,
+       0,     0,     0,     0,     0,    80,    97,     0,     0,     0,
+       0,    80,     0,    80,     0,     0,    80,     0,    97,    97,
+       0,     0,     0,     0,     0,     0,    97,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    97,    97,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    98,     0,     0,     0,     0,     0,
+       0,   121,    98,    98,     0,     0,   121,     0,     0,    98,
+       0,     0,     0,     0,    98,    98,     0,     0,     0,     0,
+      98,    98,     0,     0,     0,     0,     0,     0,     0,     0,
+      98,     0,     0,     0,     0,     0,     0,    98,     0,    97,
+      97,     0,     0,     0,     0,     0,     0,     0,   934,    98,
+      98,     0,    97,     0,     0,     0,     0,    98,     0,     0,
+       0,     0,     0,     0,     0,     0,   732,     0,     0,     0,
+       0,     0,    98,    98,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   353,   354,   355,   356,   357,   358,
+     359,   360,   361,   362,   363,   364,   365,     0,     0,   366,
+     367,    97,     0,     0,     0,     0,     0,    97,     0,    97,
+      98,     0,    97,   353,  -595,  -595,  -595,  -595,   358,   359,
+      98,    98,  -595,  -595,     0,     0,     0,     0,   366,   367,
+       0,     0,   368,    98,   369,   370,   371,   372,   373,   374,
+     375,   376,   377,   378,     0,     0,     0,     0,     0,     0,
+       0,     0,  -260,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   369,   370,   371,   372,   373,   374,   375,
+     376,   377,   378,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    98,     0,     0,     0,     0,     0,    98,     0,
+      98,  -594,     4,    98,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,     0,     0,     0,     0,     0,     0,
+      15,     0,    16,    17,    18,    19,     0,     0,     0,     0,
+       0,    20,    21,    22,    23,    24,    25,    26,     0,     0,
+      27,     0,     0,     0,     0,     0,    28,    29,    30,    31,
+      32,    33,    34,    35,    36,    37,    38,    39,     0,    40,
+      41,    42,     0,     0,    43,     0,     0,    44,    45,     0,
+      46,    47,    48,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    49,     0,     0,    50,    51,     0,    52,    53,     0,
+      54,     0,     0,    55,     0,    56,    57,    58,    59,    60,
+      61,  -466,     0,    62,  -594,     0,     0,  -594,  -594,     0,
+       0,     0,     0,     0,  -466,  -466,  -466,  -466,  -466,  -466,
+       0,  -466,     0,    63,    64,    65,     0,     0,  -466,  -466,
+       0,     0,     0,     0,     0,  -594,     0,  -594,  -466,  -466,
+       0,  -466,  -466,  -466,  -466,  -466,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   442,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,  -466,  -466,  -466,  -466,  -466,  -466,  -466,
+    -466,  -466,  -466,  -466,  -466,  -466,     0,     0,  -466,  -466,
+    -466,     0,  -466,  -466,     0,     0,     0,     0,     0,  -466,
+       0,     0,     0,     0,  -466,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,  -466,     0,     0,  -466,  -466,     0,
+    -466,  -466,     0,  -466,  -466,  -466,  -466,  -466,  -466,  -466,
+    -466,  -466,  -466,     0,     0,  -594,     0,     0,  -466,  -466,
+    -466,  -466,     0,     0,  -466,  -466,  -466,  -466,  -594,  -594,
+    -594,  -594,  -594,  -594,     0,  -594,     0,     0,     0,     0,
+       0,     0,  -594,  -594,     0,     0,     0,     0,     0,     0,
+       0,     0,  -594,  -594,     0,  -594,  -594,  -594,  -594,  -594,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,  -594,  -594,  -594,
+    -594,  -594,  -594,  -594,  -594,  -594,  -594,  -594,  -594,  -594,
+       0,     0,  -594,  -594,  -594,     0,     0,  -594,     0,     0,
+       0,     0,     0,  -594,     0,     0,     0,     0,  -594,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,  -594,     0,
+       0,  -594,  -594,     0,     0,  -594,     0,  -594,  -594,  -594,
+    -594,  -594,  -594,  -594,  -594,  -594,  -594,     0,     0,  -571,
+       0,     0,  -594,  -594,  -594,  -594,     0,   266,  -594,  -594,
+    -594,  -594,  -571,  -571,  -571,     0,  -571,  -571,     0,  -571,
+       0,     0,     0,     0,     0,  -571,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,  -571,  -571,     0,  -571,
+    -571,  -571,  -571,  -571,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,  -571,  -571,  -571,  -571,  -571,  -571,  -571,  -571,  -571,
+    -571,  -571,  -571,  -571,     0,     0,  -571,  -571,  -571,     0,
+     737,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,  -571,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,  -571,     0,     0,  -571,  -571,     0,   -99,  -571,
+       0,  -571,  -571,  -571,  -571,  -571,  -571,  -571,  -571,  -571,
+    -571,     0,     0,  -571,     0,  -571,  -571,  -571,     0,   -91,
+       0,     0,  -571,  -571,  -571,  -571,  -571,  -571,  -571,     0,
+    -571,  -571,     0,  -571,     0,     0,     0,     0,     0,  -571,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    -571,  -571,     0,  -571,  -571,  -571,  -571,  -571,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,  -571,  -571,  -571,  -571,  -571,
+    -571,  -571,  -571,  -571,  -571,  -571,  -571,  -571,     0,     0,
+    -571,  -571,  -571,     0,   737,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,  -571,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,  -571,     0,     0,  -571,
+    -571,     0,   -99,  -571,     0,  -571,  -571,  -571,  -571,  -571,
+    -571,  -571,  -571,  -571,  -571,     0,     0,  -284,     0,  -571,
+    -571,  -571,     0,  -571,     0,     0,  -571,  -571,  -571,  -571,
+    -284,  -284,  -284,     0,  -284,  -284,     0,  -284,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,  -284,  -284,     0,  -284,  -284,  -284,
+    -284,  -284,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,  -284,
+    -284,  -284,  -284,  -284,  -284,  -284,  -284,  -284,  -284,  -284,
+    -284,  -284,     0,     0,  -284,  -284,  -284,     0,   738,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    -284,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    -284,     0,     0,  -284,  -284,     0,  -101,  -284,     0,  -284,
+    -284,  -284,  -284,  -284,  -284,  -284,  -284,  -284,  -284,     0,
+       0,  -284,     0,     0,  -284,  -284,     0,   -93,     0,     0,
+    -284,  -284,  -284,  -284,  -284,  -284,  -284,     0,  -284,  -284,
+       0,  -284,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,  -284,  -284,
+       0,  -284,  -284,  -284,  -284,  -284,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,  -284,  -284,  -284,  -284,  -284,  -284,  -284,
+    -284,  -284,  -284,  -284,  -284,  -284,     0,     0,  -284,  -284,
+    -284,     0,   738,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,  -284,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,  -284,     0,     0,  -284,  -284,     0,
+    -101,  -284,     0,  -284,  -284,  -284,  -284,  -284,  -284,  -284,
+    -284,  -284,  -284,     0,     0,     0,     0,     0,  -284,  -284,
+       0,  -284,     0,     0,  -284,  -284,  -284,  -284,   284,     0,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+    -594,  -594,  -594,     0,     0,  -594,    15,     0,    16,    17,
+      18,    19,     0,     0,     0,     0,     0,    20,    21,    22,
+      23,    24,    25,    26,     0,     0,    27,     0,     0,     0,
+       0,     0,    28,     0,    30,    31,    32,    33,    34,    35,
+      36,    37,    38,    39,     0,    40,    41,    42,     0,     0,
+      43,     0,     0,    44,    45,     0,    46,    47,    48,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    49,     0,     0,
+      50,    51,     0,    52,    53,     0,    54,     0,     0,    55,
+       0,    56,    57,    58,    59,    60,    61,     0,     0,    62,
+    -594,     0,     0,  -594,  -594,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    63,
+      64,    65,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,  -594,   284,  -594,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,     0,     0,  -594,     0,  -594,  -594,
+      15,     0,    16,    17,    18,    19,     0,     0,     0,     0,
+       0,    20,    21,    22,    23,    24,    25,    26,     0,     0,
+      27,     0,     0,     0,     0,     0,    28,     0,    30,    31,
+      32,    33,    34,    35,    36,    37,    38,    39,     0,    40,
+      41,    42,     0,     0,    43,     0,     0,    44,    45,     0,
+      46,    47,    48,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    49,     0,     0,    50,    51,     0,    52,    53,     0,
+      54,     0,     0,    55,     0,    56,    57,    58,    59,    60,
+      61,     0,     0,    62,  -594,     0,     0,  -594,  -594,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    63,    64,    65,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,  -594,   284,  -594,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,     0,     0,
+    -594,     0,     0,  -594,    15,  -594,    16,    17,    18,    19,
+       0,     0,     0,     0,     0,    20,    21,    22,    23,    24,
+      25,    26,     0,     0,    27,     0,     0,     0,     0,     0,
+      28,     0,    30,    31,    32,    33,    34,    35,    36,    37,
+      38,    39,     0,    40,    41,    42,     0,     0,    43,     0,
+       0,    44,    45,     0,    46,    47,    48,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    49,     0,     0,    50,    51,
+       0,    52,    53,     0,    54,     0,     0,    55,     0,    56,
+      57,    58,    59,    60,    61,     0,     0,    62,  -594,     0,
+       0,  -594,  -594,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    63,    64,    65,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,  -594,
+     284,  -594,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,     0,     0,  -594,     0,     0,  -594,    15,     0,
+      16,    17,    18,    19,     0,     0,     0,     0,     0,    20,
+      21,    22,    23,    24,    25,    26,     0,     0,    27,     0,
+       0,     0,     0,     0,    28,     0,    30,    31,    32,    33,
+      34,    35,    36,    37,    38,    39,     0,    40,    41,    42,
+       0,     0,    43,     0,     0,    44,    45,     0,    46,    47,
+      48,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    49,
+       0,     0,    50,    51,     0,    52,    53,     0,    54,     0,
+       0,    55,     0,    56,    57,    58,    59,    60,    61,     0,
+       0,    62,  -594,     0,     0,  -594,  -594,     4,     0,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,    14,     0,
+       0,    63,    64,    65,     0,    15,     0,    16,    17,    18,
+      19,     0,     0,  -594,     0,  -594,    20,    21,    22,    23,
+      24,    25,    26,     0,     0,    27,     0,     0,     0,     0,
+       0,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+      37,    38,    39,     0,    40,    41,    42,     0,     0,    43,
+       0,     0,    44,    45,     0,    46,    47,    48,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    49,     0,     0,    50,
+      51,     0,    52,    53,     0,    54,     0,     0,    55,     0,
+      56,    57,    58,    59,    60,    61,     0,     0,    62,  -594,
+       0,     0,  -594,  -594,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    63,    64,
+      65,     0,     0,  -594,     0,     0,     0,     0,     0,     0,
+    -594,   284,  -594,     5,     6,     7,     8,     9,    10,    11,
+      12,    13,    14,     0,  -594,  -594,     0,     0,     0,    15,
+       0,    16,    17,    18,    19,     0,     0,     0,     0,     0,
+      20,    21,    22,    23,    24,    25,    26,     0,     0,    27,
+       0,     0,     0,     0,     0,    28,     0,    30,    31,    32,
+      33,    34,    35,    36,    37,    38,    39,     0,    40,    41,
+      42,     0,     0,    43,     0,     0,    44,    45,     0,    46,
+      47,    48,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      49,     0,     0,    50,    51,     0,    52,    53,     0,    54,
+       0,     0,    55,     0,    56,    57,    58,    59,    60,    61,
+       0,     0,    62,  -594,     0,     0,  -594,  -594,   284,     0,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+       0,     0,    63,    64,    65,     0,    15,     0,    16,    17,
+      18,    19,     0,     0,  -594,     0,  -594,    20,    21,    22,
+      23,    24,    25,    26,     0,     0,    27,     0,     0,     0,
+       0,     0,    28,     0,    30,    31,    32,    33,    34,    35,
+      36,    37,    38,    39,     0,    40,    41,    42,     0,     0,
+      43,     0,     0,    44,    45,     0,    46,    47,    48,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    49,     0,     0,
+     285,    51,     0,    52,    53,     0,    54,     0,     0,    55,
+       0,    56,    57,    58,    59,    60,    61,     0,     0,    62,
+    -594,     0,     0,  -594,  -594,   284,     0,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,     0,     0,    63,
+      64,    65,     0,    15,     0,    16,    17,    18,    19,     0,
+    -594,  -594,     0,  -594,    20,    21,    22,    23,    24,    25,
+      26,     0,     0,    27,     0,     0,     0,     0,     0,    28,
+       0,    30,    31,    32,    33,    34,    35,    36,    37,    38,
+      39,     0,    40,    41,    42,     0,     0,    43,     0,     0,
+      44,    45,     0,    46,    47,    48,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    49,     0,     0,    50,    51,     0,
+      52,    53,     0,    54,     0,     0,    55,     0,    56,    57,
+      58,    59,    60,    61,     0,     0,    62,  -594,     0,     0,
+    -594,  -594,   284,     0,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,     0,     0,    63,    64,    65,     0,
+      15,     0,    16,    17,    18,    19,     0,  -594,  -594,     0,
+    -594,    20,    21,    22,    23,    24,    25,    26,     0,     0,
+      27,     0,     0,     0,     0,     0,    28,     0,    30,    31,
+      32,    33,    34,    35,    36,    37,    38,    39,     0,    40,
+      41,    42,     0,     0,    43,     0,     0,    44,    45,     0,
+      46,    47,    48,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    49,     0,     0,    50,    51,     0,    52,    53,     0,
+      54,     0,     0,    55,     0,    56,    57,    58,    59,    60,
+      61,     0,     0,    62,  -594,     0,     0,  -594,  -594,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    63,    64,    65,     0,     0,  -594,     0,
+       0,     0,     0,     0,     0,  -594,   284,  -594,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,     0,     0,
+    -594,     0,     0,     0,    15,     0,    16,    17,    18,    19,
+       0,     0,     0,     0,     0,    20,    21,    22,    23,    24,
+      25,    26,     0,     0,    27,     0,     0,     0,     0,     0,
+      28,     0,    30,    31,    32,    33,    34,    35,    36,    37,
+      38,    39,     0,    40,    41,    42,     0,     0,    43,     0,
+       0,    44,    45,     0,    46,    47,    48,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    49,     0,     0,    50,    51,
+       0,    52,    53,     0,    54,     0,     0,    55,     0,    56,
+      57,    58,    59,    60,    61,     0,     0,    62,  -594,     0,
+       0,  -594,  -594,     0,     0,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,    14,     0,     0,    63,    64,    65,
+       0,    15,     0,    16,    17,    18,    19,     0,     0,  -594,
+       0,  -594,    20,    21,    22,    23,    24,    25,    26,     0,
+       0,    27,     0,     0,     0,     0,     0,    28,    29,    30,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,     0,
+      40,    41,    42,     0,     0,    43,     0,     0,    44,    45,
+       0,    46,    47,    48,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    49,     0,     0,    50,    51,     0,    52,    53,
+       0,    54,     0,     0,    55,     0,    56,    57,    58,    59,
+      60,    61,     0,     0,    62,   238,     0,     0,   239,   240,
+       0,     0,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,     0,     0,    63,    64,    65,     0,    15,     0,
+      16,    17,    18,    19,     0,     0,   241,     0,   242,    20,
+      21,    22,    23,    24,    25,    26,     0,     0,    27,     0,
+       0,     0,     0,     0,    28,     0,    30,    31,    32,    33,
+      34,    35,    36,    37,    38,    39,     0,    40,    41,    42,
+       0,     0,    43,     0,     0,    44,    45,     0,    46,    47,
+      48,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    49,
+       0,     0,    50,    51,     0,    52,    53,     0,    54,     0,
+       0,    55,     0,    56,    57,    58,    59,    60,    61,     0,
+       0,    62,   238,     0,     0,   239,   240,     0,     0,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,     0,     0,
+       0,    63,    64,    65,     0,    15,     0,    16,    17,    18,
+      19,     0,     0,   241,     0,   242,    20,    21,    22,    23,
+      24,    25,    26,     0,     0,    27,     0,     0,     0,     0,
+       0,     0,     0,     0,    31,    32,    33,    34,    35,    36,
+      37,    38,    39,     0,    40,    41,    42,     0,     0,    43,
+       0,     0,    44,    45,     0,    46,    47,    48,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   205,     0,     0,   115,
+      51,     0,    52,    53,     0,     0,     0,     0,    55,     0,
+      56,    57,    58,    59,    60,    61,     0,     0,    62,   238,
+       0,     0,   239,   240,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    63,    64,
+      65,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     241,     0,   242,   125,   126,   127,   128,   129,   130,   131,
+     132,   133,   134,   135,   136,   137,   138,   139,   140,   141,
+     142,   143,   144,   145,   146,   147,   148,     0,     0,     0,
+     149,   150,   151,   152,   153,   154,   155,   156,   157,   158,
+       0,     0,     0,     0,     0,   159,   160,   161,   162,   163,
+     164,   165,   166,    36,    37,   167,    39,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     168,   169,   170,   171,   172,   173,   174,   175,   176,     0,
+       0,   177,   178,     0,     0,   179,   180,   181,   182,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   183,
+     184,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,     0,   195,   196,     0,     0,     0,     0,     0,
+       0,   197,   198,  -564,  -564,  -564,  -564,  -564,  -564,  -564,
+    -564,  -564,     0,     0,     0,     0,     0,     0,     0,  -564,
+       0,  -564,  -564,  -564,  -564,     0,  -564,     0,     0,     0,
+    -564,  -564,  -564,  -564,  -564,  -564,  -564,     0,     0,  -564,
+       0,     0,     0,     0,     0,     0,     0,     0,  -564,  -564,
+    -564,  -564,  -564,  -564,  -564,  -564,  -564,     0,  -564,  -564,
+    -564,     0,     0,  -564,     0,     0,  -564,  -564,     0,  -564,
+    -564,  -564,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    -564,     0,     0,  -564,  -564,     0,  -564,  -564,     0,  -564,
+    -564,  -564,  -564,     0,  -564,  -564,  -564,  -564,  -564,  -564,
+       0,     0,  -564,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,  -564,  -564,  -564,     0,  -564,     0,     0,     0,
+       0,     0,  -564,  -566,  -566,  -566,  -566,  -566,  -566,  -566,
+    -566,  -566,     0,     0,     0,     0,     0,     0,     0,  -566,
+       0,  -566,  -566,  -566,  -566,     0,  -566,     0,     0,     0,
+    -566,  -566,  -566,  -566,  -566,  -566,  -566,     0,     0,  -566,
+       0,     0,     0,     0,     0,     0,     0,     0,  -566,  -566,
+    -566,  -566,  -566,  -566,  -566,  -566,  -566,     0,  -566,  -566,
+    -566,     0,     0,  -566,     0,     0,  -566,  -566,     0,  -566,
+    -566,  -566,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    -566,     0,     0,  -566,  -566,     0,  -566,  -566,     0,  -566,
+    -566,  -566,  -566,     0,  -566,  -566,  -566,  -566,  -566,  -566,
+       0,     0,  -566,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,  -566,  -566,  -566,     0,  -566,     0,     0,     0,
+       0,     0,  -566,  -565,  -565,  -565,  -565,  -565,  -565,  -565,
+    -565,  -565,     0,     0,     0,     0,     0,     0,     0,  -565,
+       0,  -565,  -565,  -565,  -565,     0,  -565,     0,     0,     0,
+    -565,  -565,  -565,  -565,  -565,  -565,  -565,     0,     0,  -565,
+       0,     0,     0,     0,     0,     0,     0,     0,  -565,  -565,
+    -565,  -565,  -565,  -565,  -565,  -565,  -565,     0,  -565,  -565,
+    -565,     0,     0,  -565,     0,     0,  -565,  -565,     0,  -565,
+    -565,  -565,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    -565,     0,     0,  -565,  -565,     0,  -565,  -565,     0,  -565,
+    -565,  -565,  -565,     0,  -565,  -565,  -565,  -565,  -565,  -565,
+       0,     0,  -565,     0,     0,     0,     0,     0,     0,  -567,
+    -567,  -567,  -567,  -567,  -567,  -567,  -567,  -567,     0,     0,
+       0,     0,  -565,  -565,  -565,  -567,  -565,  -567,  -567,  -567,
+    -567,     0,  -565,     0,     0,     0,  -567,  -567,  -567,  -567,
+    -567,  -567,  -567,     0,     0,  -567,     0,     0,     0,     0,
+       0,     0,     0,     0,  -567,  -567,  -567,  -567,  -567,  -567,
+    -567,  -567,  -567,     0,  -567,  -567,  -567,     0,     0,  -567,
+       0,     0,  -567,  -567,     0,  -567,  -567,  -567,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,  -567,   771,     0,  -567,
+    -567,     0,  -567,  -567,     0,  -567,  -567,  -567,  -567,     0,
+    -567,  -567,  -567,  -567,  -567,  -567,     0,     0,  -567,     0,
+       0,     0,     0,     0,     0,   -99,  -568,  -568,  -568,  -568,
+    -568,  -568,  -568,  -568,  -568,     0,     0,     0,  -567,  -567,
+    -567,     0,  -568,     0,  -568,  -568,  -568,  -568,  -567,     0,
+       0,     0,     0,  -568,  -568,  -568,  -568,  -568,  -568,  -568,
+       0,     0,  -568,     0,     0,     0,     0,     0,     0,     0,
+       0,  -568,  -568,  -568,  -568,  -568,  -568,  -568,  -568,  -568,
+       0,  -568,  -568,  -568,     0,     0,  -568,     0,     0,  -568,
+    -568,     0,  -568,  -568,  -568,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,  -568,   772,     0,  -568,  -568,     0,  -568,
+    -568,     0,  -568,  -568,  -568,  -568,     0,  -568,  -568,  -568,
+    -568,  -568,  -568,     0,     0,  -568,     0,     0,     0,     0,
+       0,     0,  -101,  -253,  -253,  -253,  -253,  -253,  -253,  -253,
+    -253,  -253,     0,     0,     0,  -568,  -568,  -568,     0,  -253,
+       0,  -253,  -253,  -253,  -253,  -568,     0,     0,     0,     0,
+    -253,  -253,  -253,  -253,  -253,  -253,  -253,     0,     0,  -253,
+       0,     0,     0,     0,     0,     0,     0,     0,  -253,  -253,
+    -253,  -253,  -253,  -253,  -253,  -253,  -253,     0,  -253,  -253,
+    -253,     0,     0,  -253,     0,     0,  -253,  -253,     0,  -253,
+    -253,  -253,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    -253,     0,     0,  -253,  -253,     0,  -253,  -253,     0,  -253,
+    -253,  -253,  -253,     0,  -253,  -253,  -253,  -253,  -253,  -253,
+       0,     0,  -253,     0,     0,     0,     0,     0,     0,  -569,
+    -569,  -569,  -569,  -569,  -569,  -569,  -569,  -569,     0,     0,
+       0,     0,  -253,  -253,  -253,  -569,     0,  -569,  -569,  -569,
+    -569,     0,   266,     0,     0,     0,  -569,  -569,  -569,  -569,
+    -569,  -569,  -569,     0,     0,  -569,     0,     0,     0,     0,
+       0,     0,     0,     0,  -569,  -569,  -569,  -569,  -569,  -569,
+    -569,  -569,  -569,     0,  -569,  -569,  -569,     0,     0,  -569,
+       0,     0,  -569,  -569,     0,  -569,  -569,  -569,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,  -569,     0,     0,  -569,
+    -569,     0,  -569,  -569,     0,  -569,  -569,  -569,  -569,     0,
+    -569,  -569,  -569,  -569,  -569,  -569,     0,     0,  -569,     0,
+       0,     0,     0,     0,     0,  -570,  -570,  -570,  -570,  -570,
+    -570,  -570,  -570,  -570,     0,     0,     0,     0,  -569,  -569,
+    -569,  -570,     0,  -570,  -570,  -570,  -570,     0,  -569,     0,
+       0,     0,  -570,  -570,  -570,  -570,  -570,  -570,  -570,     0,
+       0,  -570,     0,     0,     0,     0,     0,     0,     0,     0,
+    -570,  -570,  -570,  -570,  -570,  -570,  -570,  -570,  -570,     0,
+    -570,  -570,  -570,     0,     0,  -570,     0,     0,  -570,  -570,
+       0,  -570,  -570,  -570,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,  -570,     0,     0,  -570,  -570,     0,  -570,  -570,
+       0,  -570,  -570,  -570,  -570,     0,  -570,  -570,  -570,  -570,
+    -570,  -570,     0,     0,  -570,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,  -570,  -570,  -570,     0,     0,     0,
+       0,     0,     0,     0,  -570,   125,   126,   127,   128,   129,
+     130,   131,   132,   133,   134,   135,   136,   137,   138,   139,
+     140,   141,   142,   143,   144,   145,   146,   147,   148,     0,
+       0,     0,   149,   150,   151,   224,   225,   226,   227,   156,
+     157,   158,     0,     0,     0,     0,     0,   159,   160,   161,
+     228,   229,   230,   231,   166,   309,   310,   232,   311,     0,
+       0,     0,     0,     0,     0,   312,     0,     0,     0,     0,
+       0,     0,   168,   169,   170,   171,   172,   173,   174,   175,
+     176,     0,     0,   177,   178,     0,     0,   179,   180,   181,
+     182,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   183,   184,     0,     0,     0,     0,     0,     0,     0,
+     313,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   185,   186,   187,   188,   189,   190,
+     191,   192,   193,   194,     0,   195,   196,     0,     0,     0,
+       0,     0,     0,   197,   125,   126,   127,   128,   129,   130,
+     131,   132,   133,   134,   135,   136,   137,   138,   139,   140,
+     141,   142,   143,   144,   145,   146,   147,   148,     0,     0,
+       0,   149,   150,   151,   224,   225,   226,   227,   156,   157,
+     158,     0,     0,     0,     0,     0,   159,   160,   161,   228,
+     229,   230,   231,   166,   309,   310,   232,   311,     0,     0,
+       0,     0,     0,     0,   312,     0,     0,     0,     0,     0,
+       0,   168,   169,   170,   171,   172,   173,   174,   175,   176,
+       0,     0,   177,   178,     0,     0,   179,   180,   181,   182,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     183,   184,     0,     0,     0,     0,     0,     0,     0,   433,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   185,   186,   187,   188,   189,   190,   191,
+     192,   193,   194,     0,   195,   196,     0,     0,     0,     0,
+       0,     0,   197,   125,   126,   127,   128,   129,   130,   131,
+     132,   133,   134,   135,   136,   137,   138,   139,   140,   141,
+     142,   143,   144,   145,   146,   147,   148,     0,     0,     0,
+     149,   150,   151,   224,   225,   226,   227,   156,   157,   158,
+       0,     0,     0,     0,     0,   159,   160,   161,   228,   229,
+     230,   231,   166,     0,     0,   232,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     168,   169,   170,   171,   172,   173,   174,   175,   176,     0,
+       0,   177,   178,     0,     0,   179,   180,   181,   182,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   183,
+     184,     0,     0,     0,   233,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,     0,   195,   196,     0,     0,     0,     0,     0,
+       0,   197,   125,   126,   127,   128,   129,   130,   131,   132,
+     133,   134,   135,   136,   137,   138,   139,   140,   141,   142,
+     143,   144,   145,   146,   147,   148,     0,     0,     0,   149,
+     150,   151,   224,   225,   226,   227,   156,   157,   158,     0,
+       0,     0,     0,     0,   159,   160,   161,   228,   229,   230,
+     231,   166,     0,     0,   232,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   168,
+     169,   170,   171,   172,   173,   174,   175,   176,     0,     0,
+     177,   178,     0,     0,   179,   180,   181,   182,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   183,   184,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   185,   186,   187,   188,   189,   190,   191,   192,   193,
+     194,     0,   195,   196,     0,     0,     0,     0,     0,     0,
+     197,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+       0,     0,     0,     0,     0,     0,     0,    15,     0,   104,
+     105,    18,    19,     0,     0,     0,     0,     0,   106,   107,
+     108,    23,    24,    25,    26,     0,     0,   109,     0,     0,
+       0,     0,     0,     0,     0,     0,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,     0,    40,    41,    42,     0,
+       0,    43,     0,     0,    44,    45,     0,   112,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   302,     0,
+       0,   115,    51,     0,    52,    53,     0,     0,     0,     0,
+      55,     0,    56,    57,    58,    59,    60,    61,     0,     0,
+      62,     0,     0,     5,     6,     7,     8,     9,    10,    11,
+      12,    13,     0,     0,     0,     0,     0,     0,     0,    15,
+     116,   104,   105,    18,    19,     0,     0,     0,   303,     0,
+     106,   107,   108,    23,    24,    25,    26,     0,     0,   109,
+       0,     0,     0,     0,     0,     0,     0,     0,    31,    32,
+      33,    34,    35,    36,    37,    38,    39,     0,    40,    41,
+      42,     0,     0,    43,     0,     0,    44,    45,     0,   112,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     302,     0,     0,   115,    51,     0,    52,    53,     0,     0,
+       0,     0,    55,     0,    56,    57,    58,    59,    60,    61,
+       0,     0,    62,     0,     0,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,    14,     0,     0,     0,     0,     0,
+       0,    15,   116,    16,    17,    18,    19,     0,     0,     0,
+     557,     0,    20,    21,    22,    23,    24,    25,    26,     0,
+       0,    27,     0,     0,     0,     0,     0,    28,    29,    30,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,     0,
+      40,    41,    42,     0,     0,    43,     0,     0,    44,    45,
+       0,    46,    47,    48,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    49,     0,     0,    50,    51,     0,    52,    53,
+       0,    54,     0,     0,    55,     0,    56,    57,    58,    59,
+      60,    61,     0,     0,    62,     0,     0,     0,     0,     0,
+       0,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+       0,     0,     0,     0,    63,    64,    65,    15,     0,    16,
+      17,    18,    19,     0,     0,     0,     0,     0,    20,    21,
+      22,    23,    24,    25,    26,     0,     0,   109,     0,     0,
+       0,     0,     0,     0,     0,     0,    31,    32,    33,   251,
+      35,    36,    37,    38,    39,     0,    40,    41,    42,     0,
+       0,    43,     0,     0,    44,    45,     0,    46,    47,    48,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   455,     0,     0,     0,     0,     0,   205,     0,
+       0,   115,    51,     0,    52,    53,     0,   252,   253,   254,
+      55,     0,    56,    57,    58,    59,    60,    61,     0,     0,
+      62,     0,     0,     0,     0,     0,     0,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,     0,     0,     0,
+      63,   255,    65,    15,     0,    16,    17,    18,    19,     0,
+       0,     0,     0,     0,    20,    21,    22,    23,    24,    25,
+      26,     0,     0,    27,     0,     0,     0,     0,     0,    28,
+       0,    30,    31,    32,    33,    34,    35,    36,    37,    38,
+      39,     0,    40,    41,    42,     0,     0,    43,     0,     0,
+      44,    45,     0,    46,    47,    48,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    49,     0,     0,    50,    51,     0,
+      52,    53,     0,    54,     0,     0,    55,     0,    56,    57,
+      58,    59,    60,    61,     0,     0,    62,     0,     0,     0,
+       0,     0,     0,     5,     6,     7,     8,     9,    10,    11,
+      12,    13,     0,     0,     0,     0,    63,    64,    65,    15,
+       0,    16,    17,    18,    19,     0,     0,     0,     0,     0,
+      20,    21,    22,    23,    24,    25,    26,     0,     0,   109,
+       0,     0,     0,     0,     0,     0,     0,     0,    31,    32,
+      33,   251,    35,    36,    37,    38,    39,     0,    40,    41,
+      42,     0,     0,    43,     0,     0,    44,    45,     0,    46,
+      47,    48,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     205,     0,     0,   115,    51,     0,    52,    53,     0,   252,
+     253,   254,    55,     0,    56,    57,    58,    59,    60,    61,
+       0,     0,    62,     0,     0,     0,     0,     0,     0,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,     0,     0,
+       0,     0,    63,   255,    65,    15,     0,   104,   105,    18,
+      19,     0,     0,     0,     0,     0,   106,   107,   108,    23,
+      24,    25,    26,     0,     0,   109,     0,     0,     0,     0,
+       0,     0,     0,     0,    31,    32,    33,   251,    35,    36,
+      37,    38,    39,     0,    40,    41,    42,     0,     0,    43,
+       0,     0,    44,    45,     0,    46,    47,    48,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   205,     0,     0,   115,
+      51,     0,    52,    53,     0,   666,   253,   254,    55,     0,
+      56,    57,    58,    59,    60,    61,     0,     0,    62,     0,
+       0,     0,     0,     0,     0,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,     0,     0,     0,     0,    63,   255,
+      65,    15,     0,   104,   105,    18,    19,     0,     0,     0,
+       0,     0,   106,   107,   108,    23,    24,    25,    26,     0,
+       0,   109,     0,     0,     0,     0,     0,     0,     0,     0,
+      31,    32,    33,   251,    35,    36,    37,    38,    39,     0,
+      40,    41,    42,     0,     0,    43,     0,     0,    44,    45,
+       0,    46,    47,    48,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   205,     0,     0,   115,    51,     0,    52,    53,
+       0,   252,   253,     0,    55,     0,    56,    57,    58,    59,
+      60,    61,     0,     0,    62,     0,     0,     0,     0,     0,
+       0,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+       0,     0,     0,     0,    63,   255,    65,    15,     0,   104,
+     105,    18,    19,     0,     0,     0,     0,     0,   106,   107,
+     108,    23,    24,    25,    26,     0,     0,   109,     0,     0,
+       0,     0,     0,     0,     0,     0,    31,    32,    33,   251,
+      35,    36,    37,    38,    39,     0,    40,    41,    42,     0,
+       0,    43,     0,     0,    44,    45,     0,    46,    47,    48,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   205,     0,
+       0,   115,    51,     0,    52,    53,     0,     0,   253,   254,
+      55,     0,    56,    57,    58,    59,    60,    61,     0,     0,
+      62,     0,     0,     0,     0,     0,     0,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,     0,     0,     0,     0,
+      63,   255,    65,    15,     0,   104,   105,    18,    19,     0,
+       0,     0,     0,     0,   106,   107,   108,    23,    24,    25,
+      26,     0,     0,   109,     0,     0,     0,     0,     0,     0,
+       0,     0,    31,    32,    33,   251,    35,    36,    37,    38,
+      39,     0,    40,    41,    42,     0,     0,    43,     0,     0,
+      44,    45,     0,    46,    47,    48,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   205,     0,     0,   115,    51,     0,
+      52,    53,     0,   666,   253,     0,    55,     0,    56,    57,
+      58,    59,    60,    61,     0,     0,    62,     0,     0,     0,
+       0,     0,     0,     5,     6,     7,     8,     9,    10,    11,
+      12,    13,     0,     0,     0,     0,    63,   255,    65,    15,
+       0,   104,   105,    18,    19,     0,     0,     0,     0,     0,
+     106,   107,   108,    23,    24,    25,    26,     0,     0,   109,
+       0,     0,     0,     0,     0,     0,     0,     0,    31,    32,
+      33,   251,    35,    36,    37,    38,    39,     0,    40,    41,
+      42,     0,     0,    43,     0,     0,    44,    45,     0,    46,
+      47,    48,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     205,     0,     0,   115,    51,     0,    52,    53,     0,     0,
+     253,     0,    55,     0,    56,    57,    58,    59,    60,    61,
+       0,     0,    62,     0,     0,     0,     0,     0,     0,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,     0,     0,
+       0,     0,    63,   255,    65,    15,     0,    16,    17,    18,
+      19,     0,     0,     0,     0,     0,    20,    21,    22,    23,
+      24,    25,    26,     0,     0,   109,     0,     0,     0,     0,
+       0,     0,     0,     0,    31,    32,    33,    34,    35,    36,
+      37,    38,    39,     0,    40,    41,    42,     0,     0,    43,
+       0,     0,    44,    45,     0,    46,    47,    48,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   205,     0,     0,   115,
+      51,     0,    52,    53,     0,   551,     0,     0,    55,     0,
+      56,    57,    58,    59,    60,    61,     0,     0,    62,     0,
+       0,     0,     0,     0,     0,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,     0,     0,     0,     0,    63,   255,
+      65,    15,     0,   104,   105,    18,    19,     0,     0,     0,
+       0,     0,   106,   107,   108,    23,    24,    25,    26,     0,
+       0,   109,     0,     0,     0,     0,     0,     0,     0,     0,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,     0,
+      40,    41,    42,     0,     0,    43,     0,     0,    44,    45,
+       0,    46,    47,    48,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   205,     0,     0,   115,    51,     0,    52,    53,
+       0,   252,     0,     0,    55,     0,    56,    57,    58,    59,
+      60,    61,     0,     0,    62,     0,     0,     0,     0,     0,
+       0,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+       0,     0,     0,     0,    63,   255,    65,    15,     0,   104,
+     105,    18,    19,     0,     0,     0,     0,     0,   106,   107,
+     108,    23,    24,    25,    26,     0,     0,   109,     0,     0,
+       0,     0,     0,     0,     0,     0,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,     0,    40,    41,    42,     0,
+       0,    43,     0,     0,    44,    45,     0,    46,    47,    48,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   205,     0,
+       0,   115,    51,     0,    52,    53,     0,   551,     0,     0,
+      55,     0,    56,    57,    58,    59,    60,    61,     0,     0,
+      62,     0,     0,     0,     0,     0,     0,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,     0,     0,     0,     0,
+      63,   255,    65,    15,     0,   104,   105,    18,    19,     0,
+       0,     0,     0,     0,   106,   107,   108,    23,    24,    25,
+      26,     0,     0,   109,     0,     0,     0,     0,     0,     0,
+       0,     0,    31,    32,    33,    34,    35,    36,    37,    38,
+      39,     0,    40,    41,    42,     0,     0,    43,     0,     0,
+      44,    45,     0,    46,    47,    48,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   205,     0,     0,   115,    51,     0,
+      52,    53,     0,   831,     0,     0,    55,     0,    56,    57,
+      58,    59,    60,    61,     0,     0,    62,     0,     0,     0,
+       0,     0,     0,     5,     6,     7,     8,     9,    10,    11,
+      12,    13,     0,     0,     0,     0,    63,   255,    65,    15,
+       0,   104,   105,    18,    19,     0,     0,     0,     0,     0,
+     106,   107,   108,    23,    24,    25,    26,     0,     0,   109,
+       0,     0,     0,     0,     0,     0,     0,     0,    31,    32,
+      33,    34,    35,    36,    37,    38,    39,     0,    40,    41,
+      42,     0,     0,    43,     0,     0,    44,    45,     0,    46,
+      47,    48,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     205,     0,     0,   115,    51,     0,    52,    53,     0,   666,
+       0,     0,    55,     0,    56,    57,    58,    59,    60,    61,
+       0,     0,    62,     0,     0,     0,     0,     0,     0,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,     0,     0,
+       0,     0,    63,   255,    65,    15,     0,    16,    17,    18,
+      19,     0,     0,     0,     0,     0,    20,    21,    22,    23,
+      24,    25,    26,     0,     0,    27,     0,     0,     0,     0,
+       0,     0,     0,     0,    31,    32,    33,    34,    35,    36,
+      37,    38,    39,     0,    40,    41,    42,     0,     0,    43,
+       0,     0,    44,    45,     0,    46,    47,    48,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   205,     0,     0,   115,
+      51,     0,    52,    53,     0,     0,     0,     0,    55,     0,
+      56,    57,    58,    59,    60,    61,     0,     0,    62,     0,
+       0,     0,     0,     0,     0,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,     0,     0,     0,     0,    63,    64,
+      65,    15,     0,   104,   105,    18,    19,     0,     0,     0,
+       0,     0,   106,   107,   108,    23,    24,    25,    26,     0,
+       0,   109,     0,     0,     0,     0,     0,     0,     0,     0,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,     0,
+      40,    41,    42,     0,     0,    43,     0,     0,    44,    45,
+       0,    46,    47,    48,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   205,     0,     0,   115,    51,     0,    52,    53,
+       0,     0,     0,     0,    55,     0,    56,    57,    58,    59,
+      60,    61,     0,     0,    62,     0,     0,     0,     0,     0,
+       0,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+       0,     0,     0,     0,    63,   255,    65,    15,     0,    16,
+      17,    18,    19,     0,     0,     0,     0,     0,    20,    21,
+      22,    23,    24,    25,    26,     0,     0,   109,     0,     0,
+       0,     0,     0,     0,     0,     0,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,     0,    40,    41,    42,     0,
+       0,    43,     0,     0,    44,    45,     0,    46,    47,    48,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   205,     0,
+       0,   115,    51,     0,    52,    53,     0,     0,     0,     0,
+      55,     0,    56,    57,    58,    59,    60,    61,     0,     0,
+      62,     0,     0,     0,     0,     0,     0,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,     0,     0,     0,     0,
+      63,   255,    65,    15,     0,   104,   105,    18,    19,     0,
+       0,     0,     0,     0,   106,   107,   108,    23,    24,    25,
+      26,     0,     0,   109,     0,     0,     0,     0,     0,     0,
+       0,     0,    31,    32,    33,   110,    35,    36,    37,   111,
+      39,     0,    40,    41,    42,     0,     0,    43,     0,     0,
+      44,    45,     0,   112,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   113,     0,     0,   114,     0,     0,   115,    51,     0,
+      52,    53,     0,     0,     0,     0,    55,     0,    56,    57,
+      58,    59,    60,    61,     0,     0,    62,     0,     0,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,     0,     0,
+       0,     0,     0,     0,     0,    15,   116,   104,   105,    18,
+      19,     0,     0,     0,     0,     0,   106,   107,   108,    23,
+      24,    25,    26,     0,     0,   109,     0,     0,     0,     0,
+       0,     0,     0,     0,    31,    32,    33,    34,    35,    36,
+      37,    38,    39,     0,    40,    41,    42,     0,     0,    43,
+       0,     0,    44,    45,     0,   216,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   217,     0,     0,    50,
+      51,     0,    52,    53,     0,    54,     0,     0,    55,     0,
+      56,    57,    58,    59,    60,    61,     0,     0,    62,     0,
+       0,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+       0,     0,     0,     0,     0,     0,     0,    15,   116,   104,
+     105,    18,    19,     0,     0,     0,     0,     0,   106,   107,
+     108,    23,    24,    25,    26,     0,     0,   109,     0,     0,
+       0,     0,     0,     0,     0,     0,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,     0,    40,    41,    42,     0,
+       0,    43,     0,     0,    44,    45,     0,   112,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   302,     0,
+       0,   349,    51,     0,    52,    53,     0,   350,     0,     0,
+      55,     0,    56,    57,    58,    59,    60,    61,     0,     0,
+      62,     0,     0,     5,     6,     7,     8,     9,    10,    11,
+      12,    13,     0,     0,     0,     0,     0,     0,     0,    15,
+     116,   104,   105,    18,    19,     0,     0,     0,     0,     0,
+     106,   107,   108,    23,    24,    25,    26,     0,     0,   109,
+       0,     0,     0,     0,     0,     0,     0,     0,    31,    32,
+      33,   110,    35,    36,    37,   111,    39,     0,    40,    41,
+      42,     0,     0,    43,     0,     0,    44,    45,     0,   112,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     114,     0,     0,   115,    51,     0,    52,    53,     0,     0,
+       0,     0,    55,     0,    56,    57,    58,    59,    60,    61,
+       0,     0,    62,     0,     0,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,     0,     0,     0,     0,     0,     0,
+       0,    15,   116,   104,   105,    18,    19,     0,     0,     0,
+       0,     0,   106,   107,   108,    23,    24,    25,    26,     0,
+       0,   109,     0,     0,     0,     0,     0,     0,     0,     0,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,     0,
+      40,    41,    42,     0,     0,    43,     0,     0,    44,    45,
+       0,   112,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   302,     0,     0,   349,    51,     0,    52,    53,
+       0,     0,     0,     0,    55,     0,    56,    57,    58,    59,
+      60,    61,     0,     0,    62,     0,     0,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,     0,     0,     0,     0,
+       0,     0,     0,    15,   116,   104,   105,    18,    19,     0,
+       0,     0,     0,     0,   106,   107,   108,    23,    24,    25,
+      26,     0,     0,   109,     0,     0,     0,     0,     0,     0,
+       0,     0,    31,    32,    33,    34,    35,    36,    37,    38,
+      39,     0,    40,    41,    42,     0,     0,    43,     0,     0,
+      44,    45,     0,   112,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   904,     0,     0,   115,    51,     0,
+      52,    53,     0,     0,     0,     0,    55,     0,    56,    57,
+      58,    59,    60,    61,     0,     0,    62,     0,     0,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,     0,     0,
+       0,     0,     0,     0,     0,    15,   116,   104,   105,    18,
+      19,     0,     0,     0,     0,     0,   106,   107,   108,    23,
+      24,    25,    26,     0,     0,   109,     0,     0,     0,     0,
+       0,     0,     0,     0,    31,    32,    33,    34,    35,    36,
+      37,    38,    39,     0,    40,    41,    42,     0,     0,    43,
+       0,     0,    44,    45,     0,   216,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   931,     0,     0,   115,
+      51,     0,    52,    53,     0,   595,   596,     0,    55,   597,
+      56,    57,    58,    59,    60,    61,     0,     0,    62,     0,
+       0,     0,     0,     0,   168,   169,   170,   171,   172,   173,
+     174,   175,   176,     0,     0,   177,   178,     0,   116,   179,
+     180,   181,   182,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   183,   184,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   185,   186,   187,   188,
+     189,   190,   191,   192,   193,   194,     0,   195,   196,   603,
+     604,     0,     0,   605,     0,   197,   266,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   168,   169,
+     170,   171,   172,   173,   174,   175,   176,     0,     0,   177,
+     178,     0,     0,   179,   180,   181,   182,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   183,   184,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,
+       0,   195,   196,   624,   596,     0,     0,   625,     0,   197,
+     266,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   168,   169,   170,   171,   172,   173,   174,   175,
+     176,     0,     0,   177,   178,     0,     0,   179,   180,   181,
+     182,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   183,   184,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   185,   186,   187,   188,   189,   190,
+     191,   192,   193,   194,     0,   195,   196,   609,   604,     0,
+       0,   610,     0,   197,   266,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   168,   169,   170,   171,
+     172,   173,   174,   175,   176,     0,     0,   177,   178,     0,
+       0,   179,   180,   181,   182,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   183,   184,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   185,   186,
+     187,   188,   189,   190,   191,   192,   193,   194,     0,   195,
+     196,   640,   596,     0,     0,   641,     0,   197,   266,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     168,   169,   170,   171,   172,   173,   174,   175,   176,     0,
+       0,   177,   178,     0,     0,   179,   180,   181,   182,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   183,
+     184,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,     0,   195,   196,   643,   604,     0,     0,   644,
+       0,   197,   266,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   168,   169,   170,   171,   172,   173,
+     174,   175,   176,     0,     0,   177,   178,     0,     0,   179,
+     180,   181,   182,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   183,   184,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   185,   186,   187,   188,
+     189,   190,   191,   192,   193,   194,     0,   195,   196,   650,
+     596,     0,     0,   651,     0,   197,   266,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   168,   169,
+     170,   171,   172,   173,   174,   175,   176,     0,     0,   177,
+     178,     0,     0,   179,   180,   181,   182,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   183,   184,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,
+       0,   195,   196,   653,   604,     0,     0,   654,     0,   197,
+     266,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   168,   169,   170,   171,   172,   173,   174,   175,
+     176,     0,     0,   177,   178,     0,     0,   179,   180,   181,
+     182,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   183,   184,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   185,   186,   187,   188,   189,   190,
+     191,   192,   193,   194,     0,   195,   196,   689,   596,     0,
+       0,   690,     0,   197,   266,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   168,   169,   170,   171,
+     172,   173,   174,   175,   176,     0,     0,   177,   178,     0,
+       0,   179,   180,   181,   182,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   183,   184,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   185,   186,
+     187,   188,   189,   190,   191,   192,   193,   194,     0,   195,
+     196,   692,   604,     0,     0,   693,     0,   197,   266,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     168,   169,   170,   171,   172,   173,   174,   175,   176,     0,
+       0,   177,   178,     0,     0,   179,   180,   181,   182,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   183,
+     184,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,     0,   195,   196,   836,   596,     0,     0,   837,
+       0,   197,   266,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   168,   169,   170,   171,   172,   173,
+     174,   175,   176,     0,     0,   177,   178,     0,     0,   179,
+     180,   181,   182,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   183,   184,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   185,   186,   187,   188,
+     189,   190,   191,   192,   193,   194,     0,   195,   196,   839,
+     604,     0,     0,   840,     0,   197,   266,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   168,   169,
+     170,   171,   172,   173,   174,   175,   176,     0,     0,   177,
+     178,     0,     0,   179,   180,   181,   182,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   183,   184,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,
+       0,   195,   196,   994,   596,     0,     0,   995,     0,   197,
+     266,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   168,   169,   170,   171,   172,   173,   174,   175,
+     176,     0,     0,   177,   178,     0,     0,   179,   180,   181,
+     182,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   183,   184,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   185,   186,   187,   188,   189,   190,
+     191,   192,   193,   194,     0,   195,   196,  1007,   596,     0,
+       0,  1008,     0,   197,   266,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   168,   169,   170,   171,
+     172,   173,   174,   175,   176,     0,     0,   177,   178,     0,
+       0,   179,   180,   181,   182,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   183,   184,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   185,   186,
+     187,   188,   189,   190,   191,   192,   193,   194,     0,   195,
+     196,  1010,   604,     0,     0,  1011,     0,   197,   266,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     168,   169,   170,   171,   172,   173,   174,   175,   176,     0,
+       0,   177,   178,     0,     0,   179,   180,   181,   182,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   183,
+     184,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,     0,   195,   196,   609,   604,     0,     0,   610,
+       0,   197,   266,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   168,   169,   170,   171,   172,   173,
+     174,   175,   176,     0,     0,   177,   178,     0,     0,   179,
+     180,   181,   182,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   183,   184,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   732,     0,
+       0,     0,     0,     0,     0,     0,   185,   186,   187,   188,
+     189,   190,   191,   192,   193,   194,     0,   195,   196,     0,
+       0,     0,     0,     0,     0,   197,   353,   354,   355,   356,
+     357,   358,   359,   360,   361,   362,   363,   364,   365,     0,
+       0,   366,   367,   353,   354,   355,   356,   357,   358,   359,
+     360,   361,   362,   363,   364,   365,     0,     0,   366,   367,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   368,     0,   369,   370,   371,   372,
+     373,   374,   375,   376,   377,   378,     0,     0,     0,     0,
+       0,   368,     0,   369,   370,   371,   372,   373,   374,   375,
+     376,   377,   378,   353,   354,   355,   356,   357,   358,   359,
+     360,   361,   362,   363,   364,   365,     0,   242,   366,   367,
+       0,     0,   353,   354,   355,   356,   357,   358,   359,   360,
+     361,   362,   363,   364,   365,     0,     0,   366,   367,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   368,     0,   369,   370,   371,   372,   373,   374,   375,
+     376,   377,   378,     0,     0,     0,     0,     0,     0,     0,
+     368,  -260,   369,   370,   371,   372,   373,   374,   375,   376,
+     377,   378,     0,     0,     0,     0,     0,     0,     0,     0,
+    -261,   353,   354,   355,   356,   357,   358,   359,   360,   361,
+     362,   363,   364,   365,     0,     0,   366,   367,     0,     0,
+     353,   354,   355,   356,   357,   358,   359,   360,   361,   362,
+     363,   364,   365,     0,     0,   366,   367,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   368,
+       0,   369,   370,   371,   372,   373,   374,   375,   376,   377,
+     378,     0,     0,     0,     0,     0,     0,     0,   368,  -262,
+     369,   370,   371,   372,   373,   374,   375,   376,   377,   378,
+       0,     0,     0,     0,     0,     0,     0,     0,  -263,   353,
+     354,   355,   356,   357,   358,   359,   360,   361,   362,   363,
+     364,   365,     0,     0,   366,   367,     0,     0,     0,   447,
+     353,   354,   355,   356,   357,   358,   359,   360,   361,   362,
+     363,   364,   365,     0,     0,   366,   367,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   368,     0,   369,
+     370,   371,   372,   373,   374,   375,   376,   377,   378,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   368,     0,
+     369,   370,   371,   372,   373,   374,   375,   376,   377,   378,
+     353,   354,   355,   356,   357,   358,   359,   360,   361,   362,
+     363,  -595,  -595,     0,     0,   366,   367,   353,   354,   355,
+     356,   357,   358,   359,   360,     0,   362,   363,     0,     0,
+       0,     0,   366,   367,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     369,   370,   371,   372,   373,   374,   375,   376,   377,   378,
+       0,     0,     0,     0,     0,     0,     0,   369,   370,   371,
+     372,   373,   374,   375,   376,   377,   378,   353,   354,   355,
+     356,   357,   358,   359,     0,     0,   362,   363,     0,     0,
+       0,     0,   366,   367,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   369,   370,   371,
+     372,   373,   374,   375,   376,   377,   378
+};
+
+static const yytype_int16 yycheck[] =
+{
+       2,   308,   308,    83,    84,    27,   436,   213,    14,    78,
+       2,    10,     4,     5,     6,    27,    15,     9,    10,    21,
+      85,    13,    28,    15,    16,    17,     7,   262,    20,   381,
+       2,     7,     4,    28,    67,    22,     4,   303,    14,    54,
+     379,    15,   296,   454,   383,   427,   300,   386,    64,   352,
+      52,    53,    28,   405,    50,    16,    17,   721,    50,    20,
+     450,   492,    54,   320,   454,   442,   114,   406,   636,   421,
+      16,    17,    64,   484,    20,    56,   515,   645,   430,   795,
+      56,   420,   709,   422,   912,    26,    78,    57,   889,   391,
+     392,    52,   431,    67,     5,     6,    21,    22,    26,    16,
+     612,   613,    13,   142,    25,   107,    29,   146,    16,    17,
+      89,    91,    20,    25,   101,   285,    58,    59,    60,    61,
+      25,   113,    89,   115,   103,   321,   557,    57,   324,   209,
+     326,   470,   328,    89,   330,    25,    89,   289,    25,   119,
+     220,   293,   494,    54,    52,    53,    25,    16,    17,   119,
+      51,    20,    91,    27,    55,    51,   495,    53,    54,    55,
+      56,    89,   140,    26,     0,    25,   145,    78,   146,   997,
+      16,    17,   136,    69,    20,   103,   101,    91,   145,   349,
+     119,    25,   107,   108,    55,   442,   987,   706,   111,   145,
+      89,   121,   145,   407,    28,   136,   113,   352,   123,   116,
+     117,   281,   509,   509,   740,   119,    52,    53,   136,   745,
+     138,    18,   204,    20,   142,   214,   215,   145,    26,   140,
+     140,   142,   214,   215,   459,   305,   492,   144,   140,   146,
+     142,   947,    50,    80,   303,   140,   391,   392,   750,   113,
+      91,    87,   116,   117,   140,   909,   145,    72,   912,   260,
+     140,   262,   233,   140,   287,   119,    91,   233,   260,    89,
+     262,   140,   295,   296,   266,   676,   893,   300,   119,   243,
+     144,    91,   146,   136,   266,   532,   140,   124,   270,   142,
+     140,    89,   274,   275,   295,   675,   676,   279,   665,   285,
+     119,   557,   284,   285,    91,   103,   140,   115,   729,   119,
+     292,   142,   101,   455,   129,   130,   131,    89,    89,   270,
+     462,   303,   284,   287,   882,   145,    89,   119,    89,   142,
+     292,   473,   119,   123,   270,    55,   632,   126,   136,    89,
+     138,   347,   635,   997,   530,   350,   352,   145,    91,   338,
+     339,   340,   341,   140,   119,   337,   338,   339,   340,   341,
+     342,   343,   344,   349,    25,   347,   404,   349,   350,    91,
+     352,    55,   270,   145,   145,   337,   805,    91,   887,   337,
+     342,   313,   145,    16,   145,   391,   392,   113,   897,   381,
+     116,   117,   734,   822,   823,   145,   347,   119,    89,   381,
+     909,   352,   303,   140,   733,   119,   735,   266,   780,   391,
+     392,   270,   103,   405,   556,   662,    20,   383,   665,   623,
+     386,   140,   414,   405,    60,   407,   408,    63,    57,   421,
+     266,   490,   136,   492,   270,   417,   448,    72,   430,   421,
+     406,    91,   686,   425,   669,   737,   448,   138,   430,   350,
+     742,   743,   119,   435,   145,   143,   422,   458,   459,    91,
+     757,   757,   882,   137,   660,   431,   458,   459,   383,   119,
+     466,   279,   108,   729,   139,   467,    16,   285,    58,    59,
+     113,   466,   883,   116,   117,   467,    55,   119,   439,   631,
+     140,   406,  1001,   457,   476,    37,    38,   567,   557,    91,
+     466,    89,   494,   883,   470,   467,  1015,   422,   490,    91,
+     492,   144,   494,   146,   476,   103,   431,     2,   722,     4,
+     140,   513,   381,   515,     9,    10,    72,   119,    72,   495,
+      15,    16,    17,    91,   963,    20,    98,   119,    91,   786,
+      91,   349,   140,   685,   748,   381,   405,    15,   140,   531,
+     138,    13,   450,   554,   758,   470,   848,   145,   550,    16,
+     608,   119,   421,   611,   789,    50,   119,    15,   119,   405,
+     866,   430,   584,   113,    63,   557,   116,   117,   143,    64,
+     495,   629,   584,   481,   143,   421,   731,   140,    26,   490,
+     137,   492,   737,    89,   430,   140,   800,   742,   743,   113,
+     140,   140,   116,   117,   144,    16,   146,   103,    51,   417,
+      53,    54,    55,    56,   450,    51,   608,   425,   454,   611,
+     612,   613,   140,   600,    44,    89,    69,   435,   113,   140,
+     115,   608,   146,   622,   611,   494,   978,   629,    89,   103,
+     622,   623,   138,   635,   636,   481,   638,   140,   484,   145,
+     979,    89,   103,   645,   796,   859,   557,    51,   494,   660,
+     656,   140,   633,   686,    91,   103,   655,   633,   669,    51,
+     729,   656,   868,   655,   138,    58,    59,   669,   874,    16,
+      17,   145,   140,    20,   635,   600,    62,   138,    64,    65,
+     656,   746,   119,   608,   145,   697,   611,   140,   136,   139,
+     138,   119,   113,   848,   142,   116,   117,   145,    89,   139,
+      47,    48,   627,   140,   629,    52,    53,    17,    18,   204,
+     862,   863,   103,   531,    15,   731,   930,    64,    65,   214,
+     215,   737,   738,   144,    18,   146,   742,   743,   114,   115,
+     722,    51,   734,    53,    54,    55,    56,   729,   730,   731,
+     818,   819,   734,    72,   139,   737,   738,   138,   750,    69,
+     742,   743,   139,   137,   145,    15,   748,   749,   730,   735,
+     137,   763,    26,    91,   766,   139,   758,   675,   146,   768,
+     524,   266,   526,   765,   137,   270,   768,    15,   789,   274,
+     275,    92,    37,    38,   279,   777,   778,   789,    14,   284,
+     285,   119,   113,   785,    15,   116,   117,   292,   127,   128,
+     129,   130,   131,   805,   391,   392,   818,   819,   800,   801,
+     735,    62,   140,    64,    65,    15,   140,   143,   729,    51,
+     822,   823,   144,    57,   140,    89,   140,   140,   820,   675,
+     676,   140,   848,   825,   140,   140,   423,   424,   140,   103,
+      72,   140,   337,   338,   339,   340,   341,   342,   343,   344,
+      15,   139,   347,   933,   349,    15,   848,   352,   113,   137,
+      15,   116,   117,   114,   115,   734,   858,   859,   100,   101,
+      15,    15,   136,   140,   138,   867,     9,    10,   142,   871,
+     882,   145,    15,    15,   471,    89,   381,    89,   734,   144,
+     137,   146,    55,   124,   126,   124,   391,   392,   137,   103,
+      61,   103,    89,    64,    65,   252,   253,   254,   255,   820,
+     405,    15,   407,   408,   825,    89,   103,    55,   140,   266,
+     140,    61,   417,   270,    64,    65,   421,   949,    15,   103,
+     425,   749,   140,   140,   138,   430,   138,   949,   930,   140,
+     435,   145,   706,   145,   936,   709,   938,   765,    89,   941,
+      15,   138,   140,   114,   115,   142,   867,   721,   145,   777,
+     778,   963,   103,   140,   138,   113,   142,   785,   116,   117,
+     142,   145,   467,   139,   114,   115,   978,   467,   980,   981,
+     113,   476,   140,   801,    13,    26,   978,     6,   981,   987,
+      63,    64,    65,   721,   980,   207,   144,   138,   146,   494,
+     347,   213,   747,   979,   145,   352,   353,   354,   355,   356,
+     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
+     367,   368,   369,   370,   371,   372,   373,   374,   375,   376,
+     377,   378,   245,     7,   381,   721,   531,   883,   250,   866,
+     858,   114,   115,   700,   391,   392,   261,   906,    89,    26,
+      89,   909,   706,   871,   979,   809,   810,   811,   405,   813,
+      -1,   815,   103,    -1,   103,    89,    -1,     2,    -1,     4,
+       5,     6,   419,    -1,   421,    -1,   423,   424,    13,   103,
+      -1,   214,   215,   430,    89,    -1,    -1,    63,    64,    65,
+      -1,    -1,   439,    -1,    -1,   136,   443,   138,   103,   138,
+     447,   142,    -1,   450,   145,   452,   145,   454,    -1,   978,
+      -1,    -1,    89,    -1,   138,    50,    -1,    89,   936,    54,
+     938,   145,    -1,   941,   471,   337,   103,   622,   623,   893,
+      -1,   103,   978,   138,   481,    -1,    -1,   484,   114,   115,
+     145,   274,   275,    78,    -1,   909,    -1,   494,   912,    -1,
+     737,   738,    -1,    -1,    -1,   742,   743,    -1,    -1,   136,
+     655,   138,    -1,    -1,   511,   142,   138,    -1,   145,    -1,
+     696,    -1,    -1,   145,    51,   522,    53,    54,    55,    56,
+     115,    -1,    -1,   709,   771,   772,   712,   774,   775,    63,
+      64,    65,    69,   540,   541,   721,    -1,    -1,    -1,    -1,
+     954,   955,   956,   957,   551,   338,   339,   340,   341,    -1,
+     343,   344,    -1,    -1,   426,   427,    93,   700,    -1,    -1,
+     906,   704,    99,   909,   700,    -1,   912,   722,   914,    63,
+      64,    65,    -1,   997,    -1,   730,   731,    -1,   721,   734,
+     114,   115,   737,   738,    -1,   721,    -1,   742,   743,    63,
+      64,    65,    -1,   748,   749,    -1,    -1,    -1,    63,    64,
+      65,   848,    -1,   758,   476,  1019,    -1,    -1,    -1,   204,
+     765,   483,    -1,   768,    -1,   408,    -1,    -1,   964,    -1,
+     114,   115,   777,   778,    -1,    -1,    -1,    -1,   635,   876,
+     785,    40,    41,    42,    43,    44,    -1,     2,    -1,     4,
+     114,   115,    -1,    -1,    -1,   800,   801,    -1,    13,   114,
+     115,   997,    -1,   999,    -1,  1001,    -1,  1003,    -1,   666,
+      63,    64,    65,    -1,    -1,    -1,    -1,    -1,   675,   676,
+      -1,    -1,    -1,    51,    -1,    53,    54,    55,    56,    -1,
+      -1,    -1,  1028,    -1,   279,    50,    63,    64,    65,   284,
+     285,    69,    -1,   848,    72,    -1,    -1,   292,    -1,    -1,
+      -1,    -1,    -1,   858,   859,   827,   828,   893,   303,   895,
+      -1,   114,   115,   899,    -1,    93,   871,    -1,    -1,   726,
+      -1,    99,   100,   101,   731,   732,   912,   734,   914,    -1,
+     737,   738,    -1,    -1,    -1,   742,   743,   114,   115,    -1,
+      -1,    -1,   337,    -1,    -1,    -1,    -1,   342,   126,   621,
+     115,   129,    -1,    -1,   349,   350,    -1,   352,    -1,   945,
+     946,    -1,   140,   906,   771,   772,   909,   774,   775,   912,
+     906,   914,    -1,   909,    -1,   930,   912,   784,   914,    -1,
+      -1,   936,    -1,   938,    -1,    -1,   941,   909,   660,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   391,   392,    -1,   985,
+      -1,    -1,    -1,     2,   990,     4,     5,     6,     7,    -1,
+      -1,   997,   407,   999,    13,    -1,    -1,  1003,    -1,    -1,
+      -1,   964,   417,   978,   831,    -1,    -1,    -1,   964,   622,
+     425,  1017,    -1,    -1,   841,   842,    -1,    -1,    -1,   204,
+     435,   848,  1028,    -1,    -1,   967,   968,   969,    -1,   971,
+     972,    50,    -1,    -1,   997,    54,   999,    -1,  1001,    -1,
+    1003,   997,   655,   999,    -1,  1001,    -1,  1003,    -1,   876,
+      -1,    -1,   467,    -1,    72,    -1,   883,    -1,    -1,    78,
+     752,   476,    -1,    -1,    -1,  1028,    -1,   759,    -1,    87,
+      88,    72,  1028,    -1,     2,   490,     4,   492,  1020,  1021,
+    1022,  1023,    72,    -1,    -1,    -1,    87,    88,   780,    -1,
+    1032,    -1,    -1,    -1,   279,    -1,   115,    87,    88,   284,
+     285,    51,    -1,    53,    54,    55,    56,   292,   126,   127,
+     128,   129,   130,   131,   113,    -1,   531,   116,   117,    69,
+      -1,    -1,    50,   124,   125,   126,   127,   128,   129,   130,
+     131,    -1,    -1,    -1,    -1,    -1,    -1,   127,   128,   129,
+     130,   131,   557,    93,   143,   144,    -1,   146,    -1,    99,
+     113,   978,   337,   116,   117,   768,    51,   342,    53,    54,
+      55,    56,    -1,    -1,   349,    -1,    -1,   352,    51,    -1,
+      53,    54,    55,    56,    69,    -1,   868,   140,    -1,    -1,
+      -1,   144,   874,   146,    -1,   204,    69,   115,    -1,    72,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    93,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   391,   392,   623,    -1,
+      93,    -1,    -1,    -1,    -1,    -1,    99,   100,   101,    -1,
+      -1,    51,   407,    53,    54,    55,    56,    -1,    -1,    -1,
+      -1,    -1,   417,    -1,    -1,    -1,    -1,    -1,    -1,    69,
+     425,    -1,    72,   126,    -1,    -1,   129,    -1,    -1,    -1,
+     435,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   142,
+     279,    -1,    -1,    93,    -1,   284,   285,    -1,    -1,    99,
+     100,   101,    -1,   292,    -1,    -1,   204,    -1,    -1,    -1,
+      -1,    -1,   467,    -1,   303,    -1,    -1,    -1,    -1,    -1,
+      51,   476,    53,    54,    55,    56,   126,    -1,    -1,   129,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   722,    69,    -1,
+      -1,    72,   142,    -1,   729,   730,   731,    -1,   337,    -1,
+      -1,    -1,   737,   342,    -1,    -1,    -1,   742,   743,    -1,
+     349,   350,    93,   748,   749,    -1,    -1,    -1,    99,   100,
+     101,    -1,    -1,   758,    -1,    -1,   531,    -1,    -1,    -1,
+     765,   279,    -1,    -1,    -1,    -1,   284,   285,    -1,    -1,
+      -1,    -1,   777,   778,   292,   126,    -1,    -1,   129,    -1,
+     785,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,   800,   801,    -1,   407,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    51,   417,    53,
+      54,    55,    56,    -1,    -1,   820,   425,    -1,    -1,   337,
+     825,    -1,    -1,    -1,   342,    69,   435,    -1,    72,    -1,
+      -1,   349,    -1,    -1,   352,    -1,    -1,    -1,    -1,    -1,
+      84,    -1,    -1,   848,    -1,    -1,    -1,    -1,   623,    93,
+      -1,    -1,    -1,   858,   859,    99,   100,   101,   467,    -1,
+      -1,    -1,   867,    -1,    -1,    -1,   871,   476,    -1,    -1,
+      -1,    -1,    -1,   391,   392,    -1,    -1,    -1,    -1,    -1,
+      -1,   490,   126,   492,    -1,   129,    -1,    -1,    51,   407,
+      53,    54,    55,    56,    -1,    -1,    -1,    -1,    -1,   417,
+      -1,    -1,    -1,    -1,    -1,    -1,    69,   425,    -1,    72,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   435,    -1,    -1,
+      -1,    -1,   531,    -1,    -1,   930,    -1,    -1,    -1,    -1,
+      93,   936,    -1,   938,    -1,    -1,   941,   100,   101,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   722,   557,   467,
+      -1,    -1,    -1,    -1,    -1,   730,   731,    -1,   476,    -1,
+      -1,    -1,   737,   126,    -1,    -1,    -1,   742,   743,    -1,
+      -1,    -1,    -1,   748,   749,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   758,    -1,    -1,    -1,    -1,    -1,    -1,
+     765,     0,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   777,   778,    13,    14,    15,    16,    17,    18,
+     785,    20,    -1,   531,   623,    -1,    -1,    26,    27,    -1,
+      -1,    -1,    -1,    -1,    -1,   800,   801,    -1,    37,    38,
+      -1,    40,    41,    42,    43,    44,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   848,    -1,    -1,    -1,    -1,    -1,    -1,
+      89,    -1,    -1,   858,   859,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   867,    -1,   103,    -1,   871,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   113,   623,    -1,   116,   117,    -1,
+      -1,    -1,    -1,   722,    -1,    -1,    -1,    -1,    -1,    -1,
+     729,   730,    -1,    -1,    -1,    -1,    -1,   136,   137,    -1,
+      -1,    -1,    -1,   142,   143,   144,   145,   146,    -1,   748,
+     749,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   758,
+      -1,    -1,    -1,    -1,    -1,   930,   765,    -1,    -1,    -1,
+      -1,   936,    -1,   938,    -1,    -1,   941,    -1,   777,   778,
+      -1,    -1,    -1,    -1,    -1,    -1,   785,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   800,   801,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   722,    -1,    -1,    -1,    -1,    -1,
+      -1,   820,   730,   731,    -1,    -1,   825,    -1,    -1,   737,
+      -1,    -1,    -1,    -1,   742,   743,    -1,    -1,    -1,    -1,
+     748,   749,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     758,    -1,    -1,    -1,    -1,    -1,    -1,   765,    -1,   858,
+     859,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   867,   777,
+     778,    -1,   871,    -1,    -1,    -1,    -1,   785,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    44,    -1,    -1,    -1,
+      -1,    -1,   800,   801,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    72,    73,    74,    75,    76,    77,
+      78,    79,    80,    81,    82,    83,    84,    -1,    -1,    87,
+      88,   930,    -1,    -1,    -1,    -1,    -1,   936,    -1,   938,
+     848,    -1,   941,    72,    73,    74,    75,    76,    77,    78,
+     858,   859,    81,    82,    -1,    -1,    -1,    -1,    87,    88,
+      -1,    -1,   120,   871,   122,   123,   124,   125,   126,   127,
+     128,   129,   130,   131,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   140,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   122,   123,   124,   125,   126,   127,   128,
+     129,   130,   131,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   930,    -1,    -1,    -1,    -1,    -1,   936,    -1,
+     938,     0,     1,   941,     3,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    -1,    -1,    -1,    -1,    -1,    -1,
+      19,    -1,    21,    22,    23,    24,    -1,    -1,    -1,    -1,
+      -1,    30,    31,    32,    33,    34,    35,    36,    -1,    -1,
+      39,    -1,    -1,    -1,    -1,    -1,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,    54,    55,    56,    -1,    58,
+      59,    60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,
+      69,    70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,
+      99,    -1,    -1,   102,    -1,   104,   105,   106,   107,   108,
+     109,     0,    -1,   112,   113,    -1,    -1,   116,   117,    -1,
+      -1,    -1,    -1,    -1,    13,    14,    15,    16,    17,    18,
+      -1,    20,    -1,   132,   133,   134,    -1,    -1,    27,    28,
+      -1,    -1,    -1,    -1,    -1,   144,    -1,   146,    37,    38,
+      -1,    40,    41,    42,    43,    44,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    57,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    72,    73,    74,    75,    76,    77,    78,
+      79,    80,    81,    82,    83,    84,    -1,    -1,    87,    88,
+      89,    -1,    91,    92,    -1,    -1,    -1,    -1,    -1,    98,
+      -1,    -1,    -1,    -1,   103,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   113,    -1,    -1,   116,   117,    -1,
+     119,   120,    -1,   122,   123,   124,   125,   126,   127,   128,
+     129,   130,   131,    -1,    -1,     0,    -1,    -1,   137,   138,
+     139,   140,    -1,    -1,   143,   144,   145,   146,    13,    14,
+      15,    16,    17,    18,    -1,    20,    -1,    -1,    -1,    -1,
+      -1,    -1,    27,    28,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    37,    38,    -1,    40,    41,    42,    43,    44,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    72,    73,    74,
+      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
+      -1,    -1,    87,    88,    89,    -1,    -1,    92,    -1,    -1,
+      -1,    -1,    -1,    98,    -1,    -1,    -1,    -1,   103,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   113,    -1,
+      -1,   116,   117,    -1,    -1,   120,    -1,   122,   123,   124,
+     125,   126,   127,   128,   129,   130,   131,    -1,    -1,     0,
+      -1,    -1,   137,   138,   139,   140,    -1,   142,   143,   144,
+     145,   146,    13,    14,    15,    -1,    17,    18,    -1,    20,
+      -1,    -1,    -1,    -1,    -1,    26,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    37,    38,    -1,    40,
+      41,    42,    43,    44,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    72,    73,    74,    75,    76,    77,    78,    79,    80,
+      81,    82,    83,    84,    -1,    -1,    87,    88,    89,    -1,
+      91,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   103,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   113,    -1,    -1,   116,   117,    -1,   119,   120,
+      -1,   122,   123,   124,   125,   126,   127,   128,   129,   130,
+     131,    -1,    -1,     0,    -1,   136,   137,   138,    -1,   140,
+      -1,    -1,   143,   144,   145,   146,    13,    14,    15,    -1,
+      17,    18,    -1,    20,    -1,    -1,    -1,    -1,    -1,    26,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      37,    38,    -1,    40,    41,    42,    43,    44,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    72,    73,    74,    75,    76,
+      77,    78,    79,    80,    81,    82,    83,    84,    -1,    -1,
+      87,    88,    89,    -1,    91,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   103,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   113,    -1,    -1,   116,
+     117,    -1,   119,   120,    -1,   122,   123,   124,   125,   126,
+     127,   128,   129,   130,   131,    -1,    -1,     0,    -1,   136,
+     137,   138,    -1,   140,    -1,    -1,   143,   144,   145,   146,
+      13,    14,    15,    -1,    17,    18,    -1,    20,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    37,    38,    -1,    40,    41,    42,
+      43,    44,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    72,
+      73,    74,    75,    76,    77,    78,    79,    80,    81,    82,
+      83,    84,    -1,    -1,    87,    88,    89,    -1,    91,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     103,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     113,    -1,    -1,   116,   117,    -1,   119,   120,    -1,   122,
+     123,   124,   125,   126,   127,   128,   129,   130,   131,    -1,
+      -1,     0,    -1,    -1,   137,   138,    -1,   140,    -1,    -1,
+     143,   144,   145,   146,    13,    14,    15,    -1,    17,    18,
+      -1,    20,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    37,    38,
+      -1,    40,    41,    42,    43,    44,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    72,    73,    74,    75,    76,    77,    78,
+      79,    80,    81,    82,    83,    84,    -1,    -1,    87,    88,
+      89,    -1,    91,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   103,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   113,    -1,    -1,   116,   117,    -1,
+     119,   120,    -1,   122,   123,   124,   125,   126,   127,   128,
+     129,   130,   131,    -1,    -1,    -1,    -1,    -1,   137,   138,
+      -1,   140,    -1,    -1,   143,   144,   145,   146,     1,    -1,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    -1,    -1,    18,    19,    -1,    21,    22,
+      23,    24,    -1,    -1,    -1,    -1,    -1,    30,    31,    32,
+      33,    34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,
+      -1,    -1,    45,    -1,    47,    48,    49,    50,    51,    52,
+      53,    54,    55,    56,    -1,    58,    59,    60,    -1,    -1,
+      63,    -1,    -1,    66,    67,    -1,    69,    70,    71,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,
+      93,    94,    -1,    96,    97,    -1,    99,    -1,    -1,   102,
+      -1,   104,   105,   106,   107,   108,   109,    -1,    -1,   112,
+     113,    -1,    -1,   116,   117,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   132,
+     133,   134,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   144,     1,   146,     3,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    -1,    -1,    15,    -1,    17,    18,
+      19,    -1,    21,    22,    23,    24,    -1,    -1,    -1,    -1,
+      -1,    30,    31,    32,    33,    34,    35,    36,    -1,    -1,
+      39,    -1,    -1,    -1,    -1,    -1,    45,    -1,    47,    48,
+      49,    50,    51,    52,    53,    54,    55,    56,    -1,    58,
+      59,    60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,
+      69,    70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,
+      99,    -1,    -1,   102,    -1,   104,   105,   106,   107,   108,
+     109,    -1,    -1,   112,   113,    -1,    -1,   116,   117,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   132,   133,   134,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,   144,     1,   146,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    -1,    -1,
+      15,    -1,    -1,    18,    19,    20,    21,    22,    23,    24,
+      -1,    -1,    -1,    -1,    -1,    30,    31,    32,    33,    34,
+      35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,    -1,
+      45,    -1,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    -1,    58,    59,    60,    -1,    -1,    63,    -1,
+      -1,    66,    67,    -1,    69,    70,    71,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,    93,    94,
+      -1,    96,    97,    -1,    99,    -1,    -1,   102,    -1,   104,
+     105,   106,   107,   108,   109,    -1,    -1,   112,   113,    -1,
+      -1,   116,   117,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   132,   133,   134,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   144,
+       1,   146,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    -1,    -1,    15,    -1,    -1,    18,    19,    -1,
+      21,    22,    23,    24,    -1,    -1,    -1,    -1,    -1,    30,
+      31,    32,    33,    34,    35,    36,    -1,    -1,    39,    -1,
+      -1,    -1,    -1,    -1,    45,    -1,    47,    48,    49,    50,
+      51,    52,    53,    54,    55,    56,    -1,    58,    59,    60,
+      -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,    70,
+      71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    90,
+      -1,    -1,    93,    94,    -1,    96,    97,    -1,    99,    -1,
+      -1,   102,    -1,   104,   105,   106,   107,   108,   109,    -1,
+      -1,   112,   113,    -1,    -1,   116,   117,     1,    -1,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,    -1,
+      -1,   132,   133,   134,    -1,    19,    -1,    21,    22,    23,
+      24,    -1,    -1,   144,    -1,   146,    30,    31,    32,    33,
+      34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,
+      -1,    45,    46,    47,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    -1,    58,    59,    60,    -1,    -1,    63,
+      -1,    -1,    66,    67,    -1,    69,    70,    71,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,    93,
+      94,    -1,    96,    97,    -1,    99,    -1,    -1,   102,    -1,
+     104,   105,   106,   107,   108,   109,    -1,    -1,   112,   113,
+      -1,    -1,   116,   117,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   132,   133,
+     134,    -1,    -1,   137,    -1,    -1,    -1,    -1,    -1,    -1,
+     144,     1,   146,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    12,    -1,    14,    15,    -1,    -1,    -1,    19,
+      -1,    21,    22,    23,    24,    -1,    -1,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    -1,    45,    -1,    47,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    58,    59,
+      60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,
+      70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,    99,
+      -1,    -1,   102,    -1,   104,   105,   106,   107,   108,   109,
+      -1,    -1,   112,   113,    -1,    -1,   116,   117,     1,    -1,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      -1,    -1,   132,   133,   134,    -1,    19,    -1,    21,    22,
+      23,    24,    -1,    -1,   144,    -1,   146,    30,    31,    32,
+      33,    34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,
+      -1,    -1,    45,    -1,    47,    48,    49,    50,    51,    52,
+      53,    54,    55,    56,    -1,    58,    59,    60,    -1,    -1,
+      63,    -1,    -1,    66,    67,    -1,    69,    70,    71,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,
+      93,    94,    -1,    96,    97,    -1,    99,    -1,    -1,   102,
+      -1,   104,   105,   106,   107,   108,   109,    -1,    -1,   112,
+     113,    -1,    -1,   116,   117,     1,    -1,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    12,    -1,    -1,   132,
+     133,   134,    -1,    19,    -1,    21,    22,    23,    24,    -1,
+     143,   144,    -1,   146,    30,    31,    32,    33,    34,    35,
+      36,    -1,    -1,    39,    -1,    -1,    -1,    -1,    -1,    45,
+      -1,    47,    48,    49,    50,    51,    52,    53,    54,    55,
+      56,    -1,    58,    59,    60,    -1,    -1,    63,    -1,    -1,
+      66,    67,    -1,    69,    70,    71,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    90,    -1,    -1,    93,    94,    -1,
+      96,    97,    -1,    99,    -1,    -1,   102,    -1,   104,   105,
+     106,   107,   108,   109,    -1,    -1,   112,   113,    -1,    -1,
+     116,   117,     1,    -1,     3,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    -1,    -1,   132,   133,   134,    -1,
+      19,    -1,    21,    22,    23,    24,    -1,   143,   144,    -1,
+     146,    30,    31,    32,    33,    34,    35,    36,    -1,    -1,
+      39,    -1,    -1,    -1,    -1,    -1,    45,    -1,    47,    48,
+      49,    50,    51,    52,    53,    54,    55,    56,    -1,    58,
+      59,    60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,
+      69,    70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,
+      99,    -1,    -1,   102,    -1,   104,   105,   106,   107,   108,
+     109,    -1,    -1,   112,   113,    -1,    -1,   116,   117,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   132,   133,   134,    -1,    -1,   137,    -1,
+      -1,    -1,    -1,    -1,    -1,   144,     1,   146,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    -1,    -1,
+      15,    -1,    -1,    -1,    19,    -1,    21,    22,    23,    24,
+      -1,    -1,    -1,    -1,    -1,    30,    31,    32,    33,    34,
+      35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,    -1,
+      45,    -1,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    -1,    58,    59,    60,    -1,    -1,    63,    -1,
+      -1,    66,    67,    -1,    69,    70,    71,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,    93,    94,
+      -1,    96,    97,    -1,    99,    -1,    -1,   102,    -1,   104,
+     105,   106,   107,   108,   109,    -1,    -1,   112,   113,    -1,
+      -1,   116,   117,    -1,    -1,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    12,    -1,    -1,   132,   133,   134,
+      -1,    19,    -1,    21,    22,    23,    24,    -1,    -1,   144,
+      -1,   146,    30,    31,    32,    33,    34,    35,    36,    -1,
+      -1,    39,    -1,    -1,    -1,    -1,    -1,    45,    46,    47,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      58,    59,    60,    -1,    -1,    63,    -1,    -1,    66,    67,
+      -1,    69,    70,    71,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    90,    -1,    -1,    93,    94,    -1,    96,    97,
+      -1,    99,    -1,    -1,   102,    -1,   104,   105,   106,   107,
+     108,   109,    -1,    -1,   112,   113,    -1,    -1,   116,   117,
+      -1,    -1,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    -1,    -1,   132,   133,   134,    -1,    19,    -1,
+      21,    22,    23,    24,    -1,    -1,   144,    -1,   146,    30,
+      31,    32,    33,    34,    35,    36,    -1,    -1,    39,    -1,
+      -1,    -1,    -1,    -1,    45,    -1,    47,    48,    49,    50,
+      51,    52,    53,    54,    55,    56,    -1,    58,    59,    60,
+      -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,    70,
+      71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    90,
+      -1,    -1,    93,    94,    -1,    96,    97,    -1,    99,    -1,
+      -1,   102,    -1,   104,   105,   106,   107,   108,   109,    -1,
+      -1,   112,   113,    -1,    -1,   116,   117,    -1,    -1,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    -1,    -1,
+      -1,   132,   133,   134,    -1,    19,    -1,    21,    22,    23,
+      24,    -1,    -1,   144,    -1,   146,    30,    31,    32,    33,
+      34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    -1,    58,    59,    60,    -1,    -1,    63,
+      -1,    -1,    66,    67,    -1,    69,    70,    71,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,    93,
+      94,    -1,    96,    97,    -1,    -1,    -1,    -1,   102,    -1,
+     104,   105,   106,   107,   108,   109,    -1,    -1,   112,   113,
+      -1,    -1,   116,   117,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   132,   133,
+     134,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     144,    -1,   146,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,    23,    24,    25,    26,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    37,    38,    39,
+      -1,    -1,    -1,    -1,    -1,    45,    46,    47,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      70,    71,    72,    73,    74,    75,    76,    77,    78,    -1,
+      -1,    81,    82,    -1,    -1,    85,    86,    87,    88,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    99,
+     100,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   122,   123,   124,   125,   126,   127,   128,   129,
+     130,   131,    -1,   133,   134,    -1,    -1,    -1,    -1,    -1,
+      -1,   141,   142,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    19,
+      -1,    21,    22,    23,    24,    -1,    26,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    58,    59,
+      60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,
+      70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,    99,
+     100,   101,   102,    -1,   104,   105,   106,   107,   108,   109,
+      -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   132,   133,   134,    -1,   136,    -1,    -1,    -1,
+      -1,    -1,   142,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    19,
+      -1,    21,    22,    23,    24,    -1,    26,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    58,    59,
+      60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,
+      70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,    99,
+     100,   101,   102,    -1,   104,   105,   106,   107,   108,   109,
+      -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   132,   133,   134,    -1,   136,    -1,    -1,    -1,
+      -1,    -1,   142,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    19,
+      -1,    21,    22,    23,    24,    -1,    26,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    58,    59,
+      60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,
+      70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,    99,
+     100,   101,   102,    -1,   104,   105,   106,   107,   108,   109,
+      -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,    -1,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    -1,    -1,
+      -1,    -1,   132,   133,   134,    19,   136,    21,    22,    23,
+      24,    -1,   142,    -1,    -1,    -1,    30,    31,    32,    33,
+      34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    -1,    58,    59,    60,    -1,    -1,    63,
+      -1,    -1,    66,    67,    -1,    69,    70,    71,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    90,    91,    -1,    93,
+      94,    -1,    96,    97,    -1,    99,   100,   101,   102,    -1,
+     104,   105,   106,   107,   108,   109,    -1,    -1,   112,    -1,
+      -1,    -1,    -1,    -1,    -1,   119,     3,     4,     5,     6,
+       7,     8,     9,    10,    11,    -1,    -1,    -1,   132,   133,
+     134,    -1,    19,    -1,    21,    22,    23,    24,   142,    -1,
+      -1,    -1,    -1,    30,    31,    32,    33,    34,    35,    36,
+      -1,    -1,    39,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    48,    49,    50,    51,    52,    53,    54,    55,    56,
+      -1,    58,    59,    60,    -1,    -1,    63,    -1,    -1,    66,
+      67,    -1,    69,    70,    71,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    90,    91,    -1,    93,    94,    -1,    96,
+      97,    -1,    99,   100,   101,   102,    -1,   104,   105,   106,
+     107,   108,   109,    -1,    -1,   112,    -1,    -1,    -1,    -1,
+      -1,    -1,   119,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    -1,    -1,    -1,   132,   133,   134,    -1,    19,
+      -1,    21,    22,    23,    24,   142,    -1,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    58,    59,
+      60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,
+      70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,    99,
+     100,   101,   102,    -1,   104,   105,   106,   107,   108,   109,
+      -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,    -1,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    -1,    -1,
+      -1,    -1,   132,   133,   134,    19,    -1,    21,    22,    23,
+      24,    -1,   142,    -1,    -1,    -1,    30,    31,    32,    33,
+      34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    -1,    58,    59,    60,    -1,    -1,    63,
+      -1,    -1,    66,    67,    -1,    69,    70,    71,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,    93,
+      94,    -1,    96,    97,    -1,    99,   100,   101,   102,    -1,
+     104,   105,   106,   107,   108,   109,    -1,    -1,   112,    -1,
+      -1,    -1,    -1,    -1,    -1,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    -1,    -1,    -1,    -1,   132,   133,
+     134,    19,    -1,    21,    22,    23,    24,    -1,   142,    -1,
+      -1,    -1,    30,    31,    32,    33,    34,    35,    36,    -1,
+      -1,    39,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      58,    59,    60,    -1,    -1,    63,    -1,    -1,    66,    67,
+      -1,    69,    70,    71,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    90,    -1,    -1,    93,    94,    -1,    96,    97,
+      -1,    99,   100,   101,   102,    -1,   104,   105,   106,   107,
+     108,   109,    -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   132,   133,   134,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   142,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,    23,    24,    25,    26,    -1,
+      -1,    -1,    30,    31,    32,    33,    34,    35,    36,    37,
+      38,    39,    -1,    -1,    -1,    -1,    -1,    45,    46,    47,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      -1,    -1,    -1,    -1,    -1,    63,    -1,    -1,    -1,    -1,
+      -1,    -1,    70,    71,    72,    73,    74,    75,    76,    77,
+      78,    -1,    -1,    81,    82,    -1,    -1,    85,    86,    87,
+      88,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    99,   100,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     108,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   122,   123,   124,   125,   126,   127,
+     128,   129,   130,   131,    -1,   133,   134,    -1,    -1,    -1,
+      -1,    -1,    -1,   141,     3,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    -1,    -1,
+      -1,    30,    31,    32,    33,    34,    35,    36,    37,    38,
+      39,    -1,    -1,    -1,    -1,    -1,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,    54,    55,    56,    -1,    -1,
+      -1,    -1,    -1,    -1,    63,    -1,    -1,    -1,    -1,    -1,
+      -1,    70,    71,    72,    73,    74,    75,    76,    77,    78,
+      -1,    -1,    81,    82,    -1,    -1,    85,    86,    87,    88,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      99,   100,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   108,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   122,   123,   124,   125,   126,   127,   128,
+     129,   130,   131,    -1,   133,   134,    -1,    -1,    -1,    -1,
+      -1,    -1,   141,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,    23,    24,    25,    26,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    37,    38,    39,
+      -1,    -1,    -1,    -1,    -1,    45,    46,    47,    48,    49,
+      50,    51,    52,    -1,    -1,    55,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      70,    71,    72,    73,    74,    75,    76,    77,    78,    -1,
+      -1,    81,    82,    -1,    -1,    85,    86,    87,    88,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    99,
+     100,    -1,    -1,    -1,   104,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   122,   123,   124,   125,   126,   127,   128,   129,
+     130,   131,    -1,   133,   134,    -1,    -1,    -1,    -1,    -1,
+      -1,   141,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    -1,    -1,    -1,    30,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,    -1,
+      -1,    -1,    -1,    -1,    45,    46,    47,    48,    49,    50,
+      51,    52,    -1,    -1,    55,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    70,
+      71,    72,    73,    74,    75,    76,    77,    78,    -1,    -1,
+      81,    82,    -1,    -1,    85,    86,    87,    88,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    99,   100,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   122,   123,   124,   125,   126,   127,   128,   129,   130,
+     131,    -1,   133,   134,    -1,    -1,    -1,    -1,    -1,    -1,
+     141,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    19,    -1,    21,
+      22,    23,    24,    -1,    -1,    -1,    -1,    -1,    30,    31,
+      32,    33,    34,    35,    36,    -1,    -1,    39,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    48,    49,    50,    51,
+      52,    53,    54,    55,    56,    -1,    58,    59,    60,    -1,
+      -1,    63,    -1,    -1,    66,    67,    -1,    69,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,
+      -1,    93,    94,    -1,    96,    97,    -1,    -1,    -1,    -1,
+     102,    -1,   104,   105,   106,   107,   108,   109,    -1,    -1,
+     112,    -1,    -1,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    19,
+     132,    21,    22,    23,    24,    -1,    -1,    -1,   140,    -1,
+      30,    31,    32,    33,    34,    35,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    58,    59,
+      60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,    -1,
+      -1,    -1,   102,    -1,   104,   105,   106,   107,   108,   109,
+      -1,    -1,   112,    -1,    -1,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    12,    -1,    -1,    -1,    -1,    -1,
+      -1,    19,   132,    21,    22,    23,    24,    -1,    -1,    -1,
+     140,    -1,    30,    31,    32,    33,    34,    35,    36,    -1,
+      -1,    39,    -1,    -1,    -1,    -1,    -1,    45,    46,    47,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      58,    59,    60,    -1,    -1,    63,    -1,    -1,    66,    67,
+      -1,    69,    70,    71,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    90,    -1,    -1,    93,    94,    -1,    96,    97,
+      -1,    99,    -1,    -1,   102,    -1,   104,   105,   106,   107,
+     108,   109,    -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,
+      -1,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      -1,    -1,    -1,    -1,   132,   133,   134,    19,    -1,    21,
+      22,    23,    24,    -1,    -1,    -1,    -1,    -1,    30,    31,
+      32,    33,    34,    35,    36,    -1,    -1,    39,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    48,    49,    50,    51,
+      52,    53,    54,    55,    56,    -1,    58,    59,    60,    -1,
+      -1,    63,    -1,    -1,    66,    67,    -1,    69,    70,    71,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    84,    -1,    -1,    -1,    -1,    -1,    90,    -1,
+      -1,    93,    94,    -1,    96,    97,    -1,    99,   100,   101,
+     102,    -1,   104,   105,   106,   107,   108,   109,    -1,    -1,
+     112,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    12,    -1,    -1,    -1,
+     132,   133,   134,    19,    -1,    21,    22,    23,    24,    -1,
+      -1,    -1,    -1,    -1,    30,    31,    32,    33,    34,    35,
+      36,    -1,    -1,    39,    -1,    -1,    -1,    -1,    -1,    45,
+      -1,    47,    48,    49,    50,    51,    52,    53,    54,    55,
+      56,    -1,    58,    59,    60,    -1,    -1,    63,    -1,    -1,
+      66,    67,    -1,    69,    70,    71,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    90,    -1,    -1,    93,    94,    -1,
+      96,    97,    -1,    99,    -1,    -1,   102,    -1,   104,   105,
+     106,   107,   108,   109,    -1,    -1,   112,    -1,    -1,    -1,
+      -1,    -1,    -1,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    -1,    -1,    -1,    -1,   132,   133,   134,    19,
+      -1,    21,    22,    23,    24,    -1,    -1,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    58,    59,
+      60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,
+      70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,    99,
+     100,   101,   102,    -1,   104,   105,   106,   107,   108,   109,
+      -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,    -1,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    -1,    -1,
+      -1,    -1,   132,   133,   134,    19,    -1,    21,    22,    23,
+      24,    -1,    -1,    -1,    -1,    -1,    30,    31,    32,    33,
+      34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    -1,    58,    59,    60,    -1,    -1,    63,
+      -1,    -1,    66,    67,    -1,    69,    70,    71,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,    93,
+      94,    -1,    96,    97,    -1,    99,   100,   101,   102,    -1,
+     104,   105,   106,   107,   108,   109,    -1,    -1,   112,    -1,
+      -1,    -1,    -1,    -1,    -1,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    -1,    -1,    -1,    -1,   132,   133,
+     134,    19,    -1,    21,    22,    23,    24,    -1,    -1,    -1,
+      -1,    -1,    30,    31,    32,    33,    34,    35,    36,    -1,
+      -1,    39,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      58,    59,    60,    -1,    -1,    63,    -1,    -1,    66,    67,
+      -1,    69,    70,    71,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    90,    -1,    -1,    93,    94,    -1,    96,    97,
+      -1,    99,   100,    -1,   102,    -1,   104,   105,   106,   107,
+     108,   109,    -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,
+      -1,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      -1,    -1,    -1,    -1,   132,   133,   134,    19,    -1,    21,
+      22,    23,    24,    -1,    -1,    -1,    -1,    -1,    30,    31,
+      32,    33,    34,    35,    36,    -1,    -1,    39,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    48,    49,    50,    51,
+      52,    53,    54,    55,    56,    -1,    58,    59,    60,    -1,
+      -1,    63,    -1,    -1,    66,    67,    -1,    69,    70,    71,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,
+      -1,    93,    94,    -1,    96,    97,    -1,    -1,   100,   101,
+     102,    -1,   104,   105,   106,   107,   108,   109,    -1,    -1,
+     112,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    -1,    -1,    -1,    -1,
+     132,   133,   134,    19,    -1,    21,    22,    23,    24,    -1,
+      -1,    -1,    -1,    -1,    30,    31,    32,    33,    34,    35,
+      36,    -1,    -1,    39,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    48,    49,    50,    51,    52,    53,    54,    55,
+      56,    -1,    58,    59,    60,    -1,    -1,    63,    -1,    -1,
+      66,    67,    -1,    69,    70,    71,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    90,    -1,    -1,    93,    94,    -1,
+      96,    97,    -1,    99,   100,    -1,   102,    -1,   104,   105,
+     106,   107,   108,   109,    -1,    -1,   112,    -1,    -1,    -1,
+      -1,    -1,    -1,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    -1,    -1,    -1,    -1,   132,   133,   134,    19,
+      -1,    21,    22,    23,    24,    -1,    -1,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    58,    59,
+      60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,
+      70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,    -1,
+     100,    -1,   102,    -1,   104,   105,   106,   107,   108,   109,
+      -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,    -1,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    -1,    -1,
+      -1,    -1,   132,   133,   134,    19,    -1,    21,    22,    23,
+      24,    -1,    -1,    -1,    -1,    -1,    30,    31,    32,    33,
+      34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    -1,    58,    59,    60,    -1,    -1,    63,
+      -1,    -1,    66,    67,    -1,    69,    70,    71,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,    93,
+      94,    -1,    96,    97,    -1,    99,    -1,    -1,   102,    -1,
+     104,   105,   106,   107,   108,   109,    -1,    -1,   112,    -1,
+      -1,    -1,    -1,    -1,    -1,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    -1,    -1,    -1,    -1,   132,   133,
+     134,    19,    -1,    21,    22,    23,    24,    -1,    -1,    -1,
+      -1,    -1,    30,    31,    32,    33,    34,    35,    36,    -1,
+      -1,    39,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      58,    59,    60,    -1,    -1,    63,    -1,    -1,    66,    67,
+      -1,    69,    70,    71,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    90,    -1,    -1,    93,    94,    -1,    96,    97,
+      -1,    99,    -1,    -1,   102,    -1,   104,   105,   106,   107,
+     108,   109,    -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,
+      -1,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      -1,    -1,    -1,    -1,   132,   133,   134,    19,    -1,    21,
+      22,    23,    24,    -1,    -1,    -1,    -1,    -1,    30,    31,
+      32,    33,    34,    35,    36,    -1,    -1,    39,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    48,    49,    50,    51,
+      52,    53,    54,    55,    56,    -1,    58,    59,    60,    -1,
+      -1,    63,    -1,    -1,    66,    67,    -1,    69,    70,    71,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,
+      -1,    93,    94,    -1,    96,    97,    -1,    99,    -1,    -1,
+     102,    -1,   104,   105,   106,   107,   108,   109,    -1,    -1,
+     112,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    -1,    -1,    -1,    -1,
+     132,   133,   134,    19,    -1,    21,    22,    23,    24,    -1,
+      -1,    -1,    -1,    -1,    30,    31,    32,    33,    34,    35,
+      36,    -1,    -1,    39,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    48,    49,    50,    51,    52,    53,    54,    55,
+      56,    -1,    58,    59,    60,    -1,    -1,    63,    -1,    -1,
+      66,    67,    -1,    69,    70,    71,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    90,    -1,    -1,    93,    94,    -1,
+      96,    97,    -1,    99,    -1,    -1,   102,    -1,   104,   105,
+     106,   107,   108,   109,    -1,    -1,   112,    -1,    -1,    -1,
+      -1,    -1,    -1,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    -1,    -1,    -1,    -1,   132,   133,   134,    19,
+      -1,    21,    22,    23,    24,    -1,    -1,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    58,    59,
+      60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,
+      70,    71,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,    99,
+      -1,    -1,   102,    -1,   104,   105,   106,   107,   108,   109,
+      -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,    -1,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    -1,    -1,
+      -1,    -1,   132,   133,   134,    19,    -1,    21,    22,    23,
+      24,    -1,    -1,    -1,    -1,    -1,    30,    31,    32,    33,
+      34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    -1,    58,    59,    60,    -1,    -1,    63,
+      -1,    -1,    66,    67,    -1,    69,    70,    71,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,    93,
+      94,    -1,    96,    97,    -1,    -1,    -1,    -1,   102,    -1,
+     104,   105,   106,   107,   108,   109,    -1,    -1,   112,    -1,
+      -1,    -1,    -1,    -1,    -1,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    -1,    -1,    -1,    -1,   132,   133,
+     134,    19,    -1,    21,    22,    23,    24,    -1,    -1,    -1,
+      -1,    -1,    30,    31,    32,    33,    34,    35,    36,    -1,
+      -1,    39,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      58,    59,    60,    -1,    -1,    63,    -1,    -1,    66,    67,
+      -1,    69,    70,    71,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    90,    -1,    -1,    93,    94,    -1,    96,    97,
+      -1,    -1,    -1,    -1,   102,    -1,   104,   105,   106,   107,
+     108,   109,    -1,    -1,   112,    -1,    -1,    -1,    -1,    -1,
+      -1,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      -1,    -1,    -1,    -1,   132,   133,   134,    19,    -1,    21,
+      22,    23,    24,    -1,    -1,    -1,    -1,    -1,    30,    31,
+      32,    33,    34,    35,    36,    -1,    -1,    39,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    48,    49,    50,    51,
+      52,    53,    54,    55,    56,    -1,    58,    59,    60,    -1,
+      -1,    63,    -1,    -1,    66,    67,    -1,    69,    70,    71,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,
+      -1,    93,    94,    -1,    96,    97,    -1,    -1,    -1,    -1,
+     102,    -1,   104,   105,   106,   107,   108,   109,    -1,    -1,
+     112,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    -1,    -1,    -1,    -1,
+     132,   133,   134,    19,    -1,    21,    22,    23,    24,    -1,
+      -1,    -1,    -1,    -1,    30,    31,    32,    33,    34,    35,
+      36,    -1,    -1,    39,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    48,    49,    50,    51,    52,    53,    54,    55,
+      56,    -1,    58,    59,    60,    -1,    -1,    63,    -1,    -1,
+      66,    67,    -1,    69,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    87,    -1,    -1,    90,    -1,    -1,    93,    94,    -1,
+      96,    97,    -1,    -1,    -1,    -1,   102,    -1,   104,   105,
+     106,   107,   108,   109,    -1,    -1,   112,    -1,    -1,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    19,   132,    21,    22,    23,
+      24,    -1,    -1,    -1,    -1,    -1,    30,    31,    32,    33,
+      34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    -1,    58,    59,    60,    -1,    -1,    63,
+      -1,    -1,    66,    67,    -1,    69,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,    93,
+      94,    -1,    96,    97,    -1,    99,    -1,    -1,   102,    -1,
+     104,   105,   106,   107,   108,   109,    -1,    -1,   112,    -1,
+      -1,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    19,   132,    21,
+      22,    23,    24,    -1,    -1,    -1,    -1,    -1,    30,    31,
+      32,    33,    34,    35,    36,    -1,    -1,    39,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    48,    49,    50,    51,
+      52,    53,    54,    55,    56,    -1,    58,    59,    60,    -1,
+      -1,    63,    -1,    -1,    66,    67,    -1,    69,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,
+      -1,    93,    94,    -1,    96,    97,    -1,    99,    -1,    -1,
+     102,    -1,   104,   105,   106,   107,   108,   109,    -1,    -1,
+     112,    -1,    -1,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    19,
+     132,    21,    22,    23,    24,    -1,    -1,    -1,    -1,    -1,
+      30,    31,    32,    33,    34,    35,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,    58,    59,
+      60,    -1,    -1,    63,    -1,    -1,    66,    67,    -1,    69,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    94,    -1,    96,    97,    -1,    -1,
+      -1,    -1,   102,    -1,   104,   105,   106,   107,   108,   109,
+      -1,    -1,   112,    -1,    -1,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    19,   132,    21,    22,    23,    24,    -1,    -1,    -1,
+      -1,    -1,    30,    31,    32,    33,    34,    35,    36,    -1,
+      -1,    39,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      58,    59,    60,    -1,    -1,    63,    -1,    -1,    66,    67,
+      -1,    69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    90,    -1,    -1,    93,    94,    -1,    96,    97,
+      -1,    -1,    -1,    -1,   102,    -1,   104,   105,   106,   107,
+     108,   109,    -1,    -1,   112,    -1,    -1,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    19,   132,    21,    22,    23,    24,    -1,
+      -1,    -1,    -1,    -1,    30,    31,    32,    33,    34,    35,
+      36,    -1,    -1,    39,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    48,    49,    50,    51,    52,    53,    54,    55,
+      56,    -1,    58,    59,    60,    -1,    -1,    63,    -1,    -1,
+      66,    67,    -1,    69,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    90,    -1,    -1,    93,    94,    -1,
+      96,    97,    -1,    -1,    -1,    -1,   102,    -1,   104,   105,
+     106,   107,   108,   109,    -1,    -1,   112,    -1,    -1,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    19,   132,    21,    22,    23,
+      24,    -1,    -1,    -1,    -1,    -1,    30,    31,    32,    33,
+      34,    35,    36,    -1,    -1,    39,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    -1,    58,    59,    60,    -1,    -1,    63,
+      -1,    -1,    66,    67,    -1,    69,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,    93,
+      94,    -1,    96,    97,    -1,    51,    52,    -1,   102,    55,
+     104,   105,   106,   107,   108,   109,    -1,    -1,   112,    -1,
+      -1,    -1,    -1,    -1,    70,    71,    72,    73,    74,    75,
+      76,    77,    78,    -1,    -1,    81,    82,    -1,   132,    85,
+      86,    87,    88,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    99,   100,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   122,   123,   124,   125,
+     126,   127,   128,   129,   130,   131,    -1,   133,   134,    51,
+      52,    -1,    -1,    55,    -1,   141,   142,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    70,    71,
+      72,    73,    74,    75,    76,    77,    78,    -1,    -1,    81,
+      82,    -1,    -1,    85,    86,    87,    88,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    99,   100,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     122,   123,   124,   125,   126,   127,   128,   129,   130,   131,
+      -1,   133,   134,    51,    52,    -1,    -1,    55,    -1,   141,
+     142,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    70,    71,    72,    73,    74,    75,    76,    77,
+      78,    -1,    -1,    81,    82,    -1,    -1,    85,    86,    87,
+      88,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    99,   100,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   122,   123,   124,   125,   126,   127,
+     128,   129,   130,   131,    -1,   133,   134,    51,    52,    -1,
+      -1,    55,    -1,   141,   142,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    70,    71,    72,    73,
+      74,    75,    76,    77,    78,    -1,    -1,    81,    82,    -1,
+      -1,    85,    86,    87,    88,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    99,   100,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   122,   123,
+     124,   125,   126,   127,   128,   129,   130,   131,    -1,   133,
+     134,    51,    52,    -1,    -1,    55,    -1,   141,   142,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      70,    71,    72,    73,    74,    75,    76,    77,    78,    -1,
+      -1,    81,    82,    -1,    -1,    85,    86,    87,    88,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    99,
+     100,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   122,   123,   124,   125,   126,   127,   128,   129,
+     130,   131,    -1,   133,   134,    51,    52,    -1,    -1,    55,
+      -1,   141,   142,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    70,    71,    72,    73,    74,    75,
+      76,    77,    78,    -1,    -1,    81,    82,    -1,    -1,    85,
+      86,    87,    88,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    99,   100,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   122,   123,   124,   125,
+     126,   127,   128,   129,   130,   131,    -1,   133,   134,    51,
+      52,    -1,    -1,    55,    -1,   141,   142,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    70,    71,
+      72,    73,    74,    75,    76,    77,    78,    -1,    -1,    81,
+      82,    -1,    -1,    85,    86,    87,    88,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    99,   100,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     122,   123,   124,   125,   126,   127,   128,   129,   130,   131,
+      -1,   133,   134,    51,    52,    -1,    -1,    55,    -1,   141,
+     142,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    70,    71,    72,    73,    74,    75,    76,    77,
+      78,    -1,    -1,    81,    82,    -1,    -1,    85,    86,    87,
+      88,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    99,   100,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   122,   123,   124,   125,   126,   127,
+     128,   129,   130,   131,    -1,   133,   134,    51,    52,    -1,
+      -1,    55,    -1,   141,   142,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    70,    71,    72,    73,
+      74,    75,    76,    77,    78,    -1,    -1,    81,    82,    -1,
+      -1,    85,    86,    87,    88,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    99,   100,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   122,   123,
+     124,   125,   126,   127,   128,   129,   130,   131,    -1,   133,
+     134,    51,    52,    -1,    -1,    55,    -1,   141,   142,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      70,    71,    72,    73,    74,    75,    76,    77,    78,    -1,
+      -1,    81,    82,    -1,    -1,    85,    86,    87,    88,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    99,
+     100,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   122,   123,   124,   125,   126,   127,   128,   129,
+     130,   131,    -1,   133,   134,    51,    52,    -1,    -1,    55,
+      -1,   141,   142,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    70,    71,    72,    73,    74,    75,
+      76,    77,    78,    -1,    -1,    81,    82,    -1,    -1,    85,
+      86,    87,    88,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    99,   100,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   122,   123,   124,   125,
+     126,   127,   128,   129,   130,   131,    -1,   133,   134,    51,
+      52,    -1,    -1,    55,    -1,   141,   142,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    70,    71,
+      72,    73,    74,    75,    76,    77,    78,    -1,    -1,    81,
+      82,    -1,    -1,    85,    86,    87,    88,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    99,   100,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     122,   123,   124,   125,   126,   127,   128,   129,   130,   131,
+      -1,   133,   134,    51,    52,    -1,    -1,    55,    -1,   141,
+     142,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    70,    71,    72,    73,    74,    75,    76,    77,
+      78,    -1,    -1,    81,    82,    -1,    -1,    85,    86,    87,
+      88,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    99,   100,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   122,   123,   124,   125,   126,   127,
+     128,   129,   130,   131,    -1,   133,   134,    51,    52,    -1,
+      -1,    55,    -1,   141,   142,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    70,    71,    72,    73,
+      74,    75,    76,    77,    78,    -1,    -1,    81,    82,    -1,
+      -1,    85,    86,    87,    88,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    99,   100,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   122,   123,
+     124,   125,   126,   127,   128,   129,   130,   131,    -1,   133,
+     134,    51,    52,    -1,    -1,    55,    -1,   141,   142,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      70,    71,    72,    73,    74,    75,    76,    77,    78,    -1,
+      -1,    81,    82,    -1,    -1,    85,    86,    87,    88,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    99,
+     100,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   122,   123,   124,   125,   126,   127,   128,   129,
+     130,   131,    -1,   133,   134,    51,    52,    -1,    -1,    55,
+      -1,   141,   142,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    70,    71,    72,    73,    74,    75,
+      76,    77,    78,    -1,    -1,    81,    82,    -1,    -1,    85,
+      86,    87,    88,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    99,   100,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    44,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   122,   123,   124,   125,
+     126,   127,   128,   129,   130,   131,    -1,   133,   134,    -1,
+      -1,    -1,    -1,    -1,    -1,   141,    72,    73,    74,    75,
+      76,    77,    78,    79,    80,    81,    82,    83,    84,    -1,
+      -1,    87,    88,    72,    73,    74,    75,    76,    77,    78,
+      79,    80,    81,    82,    83,    84,    -1,    -1,    87,    88,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   120,    -1,   122,   123,   124,   125,
+     126,   127,   128,   129,   130,   131,    -1,    -1,    -1,    -1,
+      -1,   120,    -1,   122,   123,   124,   125,   126,   127,   128,
+     129,   130,   131,    72,    73,    74,    75,    76,    77,    78,
+      79,    80,    81,    82,    83,    84,    -1,   146,    87,    88,
+      -1,    -1,    72,    73,    74,    75,    76,    77,    78,    79,
+      80,    81,    82,    83,    84,    -1,    -1,    87,    88,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   120,    -1,   122,   123,   124,   125,   126,   127,   128,
+     129,   130,   131,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     120,   140,   122,   123,   124,   125,   126,   127,   128,   129,
+     130,   131,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     140,    72,    73,    74,    75,    76,    77,    78,    79,    80,
+      81,    82,    83,    84,    -1,    -1,    87,    88,    -1,    -1,
+      72,    73,    74,    75,    76,    77,    78,    79,    80,    81,
+      82,    83,    84,    -1,    -1,    87,    88,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   120,
+      -1,   122,   123,   124,   125,   126,   127,   128,   129,   130,
+     131,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   120,   140,
+     122,   123,   124,   125,   126,   127,   128,   129,   130,   131,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   140,    72,
+      73,    74,    75,    76,    77,    78,    79,    80,    81,    82,
+      83,    84,    -1,    -1,    87,    88,    -1,    -1,    -1,    92,
+      72,    73,    74,    75,    76,    77,    78,    79,    80,    81,
+      82,    83,    84,    -1,    -1,    87,    88,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   120,    -1,   122,
+     123,   124,   125,   126,   127,   128,   129,   130,   131,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   120,    -1,
+     122,   123,   124,   125,   126,   127,   128,   129,   130,   131,
+      72,    73,    74,    75,    76,    77,    78,    79,    80,    81,
+      82,    83,    84,    -1,    -1,    87,    88,    72,    73,    74,
+      75,    76,    77,    78,    79,    -1,    81,    82,    -1,    -1,
+      -1,    -1,    87,    88,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     122,   123,   124,   125,   126,   127,   128,   129,   130,   131,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   122,   123,   124,
+     125,   126,   127,   128,   129,   130,   131,    72,    73,    74,
+      75,    76,    77,    78,    -1,    -1,    81,    82,    -1,    -1,
+      -1,    -1,    87,    88,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   122,   123,   124,
+     125,   126,   127,   128,   129,   130,   131
+};
+
+  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+     symbol of state STATE-NUM.  */
+static const yytype_int16 yystos[] =
+{
+       0,   148,   149,     0,     1,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    12,    19,    21,    22,    23,    24,
+      30,    31,    32,    33,    34,    35,    36,    39,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
+      58,    59,    60,    63,    66,    67,    69,    70,    71,    90,
+      93,    94,    96,    97,    99,   102,   104,   105,   106,   107,
+     108,   109,   112,   132,   133,   134,   150,   151,   152,   157,
+     159,   161,   163,   164,   167,   168,   170,   171,   172,   174,
+     175,   184,   198,   219,   240,   241,   251,   252,   253,   257,
+     258,   259,   265,   266,   267,   269,   270,   271,   272,   273,
+     274,   309,   322,   152,    21,    22,    30,    31,    32,    39,
+      51,    55,    69,    87,    90,    93,   132,   176,   177,   198,
+     219,   271,   274,   309,   177,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,    23,    24,    25,    26,    30,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,    45,
+      46,    47,    48,    49,    50,    51,    52,    55,    70,    71,
+      72,    73,    74,    75,    76,    77,    78,    81,    82,    85,
+      86,    87,    88,    99,   100,   122,   123,   124,   125,   126,
+     127,   128,   129,   130,   131,   133,   134,   141,   142,   178,
+     182,   183,   273,   303,   199,    90,   161,   162,   175,   219,
+     271,   272,   274,   162,   205,   207,    69,    90,   168,   175,
+     219,   224,   271,   274,    33,    34,    35,    36,    48,    49,
+      50,    51,    55,   104,   178,   179,   180,   267,   113,   116,
+     117,   144,   146,   162,   261,   262,   263,   315,   319,   320,
+     321,    51,    99,   100,   101,   133,   167,   184,   190,   193,
+     196,   253,   306,   308,   190,   190,   142,   187,   188,   191,
+     192,   322,   187,   191,   142,   316,   320,   179,   153,   136,
+     184,   219,   184,    55,     1,    93,   155,   156,   157,   169,
+     170,   322,   200,   202,   185,   196,   306,   322,   184,   305,
+     306,   322,    90,   140,   174,   219,   271,   274,   203,    53,
+      54,    56,    63,   108,   178,   268,    62,    64,    65,   114,
+     115,   254,   255,    63,   254,    63,   254,    63,   254,    61,
+     254,    58,    59,   163,   184,   184,   315,   321,    40,    41,
+      42,    43,    44,    37,    38,    28,   238,   119,   140,    93,
+      99,   171,   119,    72,    73,    74,    75,    76,    77,    78,
+      79,    80,    81,    82,    83,    84,    87,    88,   120,   122,
+     123,   124,   125,   126,   127,   128,   129,   130,   131,    89,
+     103,   138,   145,   313,    89,   313,   314,    26,   136,   242,
+     253,    91,    91,   187,   191,   242,   161,    51,    55,   176,
+      58,    59,   123,   275,    89,   138,   313,   214,   304,   215,
+      89,   145,   312,   154,   155,    55,    16,   220,   319,   119,
+      89,   138,   313,    91,    91,   220,   162,   162,    55,    89,
+     138,   313,    25,   108,   140,   264,   315,   113,   263,    20,
+     245,   319,    57,   307,   184,   184,   184,    92,   140,   194,
+     195,   322,   307,   194,   195,    84,   189,   190,   196,   306,
+     322,   190,   161,   315,   317,   161,   158,   136,   155,    89,
+     313,    91,   157,   169,   143,   315,   321,   317,   157,   317,
+     139,   195,   318,   321,   195,   318,   137,   318,    55,   171,
+     172,   173,   140,    89,   138,   313,    51,    53,    54,    55,
+      56,    69,    72,    93,    99,   100,   101,   126,   129,   142,
+     236,   278,   279,   282,   283,   284,   285,   287,   288,   289,
+     290,   292,   293,   294,   297,   298,   299,   300,   301,    63,
+     254,   256,   260,   261,    62,   255,    63,    63,    63,    61,
+      72,    72,   152,   162,   162,   162,   162,   157,   161,   161,
+     239,    99,   163,   184,   196,   197,   169,   140,   174,   140,
+     159,   160,   163,   175,   184,   186,   197,   219,   274,   184,
+     184,   184,   184,   184,   184,   184,   184,   184,   184,   184,
+     184,   184,   184,   184,   184,   184,   184,   184,   184,   184,
+     184,   184,   184,   184,   184,    51,    52,    55,   182,   187,
+     310,   311,   189,    51,    52,    55,   182,   187,   310,    51,
+      55,   310,   244,   243,   160,   184,   186,   160,   186,    98,
+     165,   212,   276,   211,    51,    55,   176,   310,   189,   310,
+     154,   161,   216,   217,    15,    13,   247,   322,   155,    16,
+      51,    55,   189,    51,    55,   155,    27,   221,   319,   221,
+      51,    55,   189,    51,    55,   209,   181,   155,   245,   184,
+     196,    15,   260,   184,   184,   316,    99,   184,   193,   306,
+     184,   308,   317,   143,   315,   195,   195,   317,   143,   179,
+     150,   137,   186,   317,   157,   201,   306,   171,   173,    51,
+      55,   189,    51,    55,    57,   119,   291,   287,   204,   184,
+     140,   302,   322,    51,   140,   302,   140,   286,   184,   140,
+     286,    51,   140,   286,    51,    63,   155,   261,   184,   184,
+      80,   124,   230,   231,   322,   184,   195,   317,   173,   140,
+      44,   119,    44,    89,   138,   313,   316,    91,    91,   187,
+     191,   139,    91,    91,   188,   191,   188,   191,   230,   230,
+     166,   319,   162,   154,   139,    15,   317,   142,   277,   287,
+     178,   184,   197,   248,   322,    18,   223,   322,    17,   222,
+     223,    91,    91,   139,    91,    91,   223,   206,   208,   139,
+     162,   179,   137,    15,   195,   220,   260,   184,   194,   306,
+     137,   317,   318,   139,    51,    99,   225,   292,   233,   316,
+      29,   111,   237,    51,   279,   284,   301,   285,   290,   297,
+     299,   292,   294,   299,    51,   292,   137,   227,   229,   232,
+     278,   280,   281,   284,   292,   293,   295,   296,   299,   301,
+     154,    99,   184,   173,   157,   184,    51,    55,   189,    51,
+      55,    57,   121,   160,   186,   163,   186,   165,    91,   160,
+     186,   160,   186,   165,   242,   238,   154,   155,   230,   213,
+     319,    15,    84,   287,   154,   319,   218,    92,   249,   322,
+     155,    14,   250,   322,   162,    15,    91,    15,   155,   155,
+     221,   184,   155,   195,   140,   289,   317,   140,   143,   144,
+     154,   155,   302,   140,   286,   140,   286,   140,   286,   140,
+     286,   286,   233,   233,    90,   219,   140,   302,   302,   140,
+     228,   219,   140,   228,   140,   228,    15,   184,   139,   184,
+     184,   160,   186,    15,   137,   155,   154,   317,   317,    15,
+     277,    90,   175,   219,   271,   274,   220,   155,   220,    15,
+      15,   210,   223,   245,   246,   226,   140,    99,    51,   234,
+     235,   288,    15,   137,   292,   299,   292,   292,   124,   124,
+      55,    89,   280,   284,   140,   227,   228,   296,   299,   292,
+     295,   299,   292,   137,    15,   154,    55,    89,   138,   313,
+     155,   155,   155,   292,   292,   140,   289,   140,   316,   286,
+     140,   286,   286,   286,    51,    55,   302,   140,   228,   140,
+     228,   140,   228,   140,   228,   228,    15,    51,    55,   189,
+      51,    55,   247,   222,    15,   140,   292,   140,   235,   292,
+     292,   299,   292,   292,   139,   292,   286,   228,   140,   228,
+     228,   228,   292,   228
+};
+
+  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_int16 yyr1[] =
+{
+       0,   147,   149,   148,   150,   151,   151,   151,   151,   152,
+     153,   152,   154,   155,   156,   156,   156,   156,   158,   157,
+     157,   157,   157,   157,   157,   157,   157,   157,   157,   157,
+     157,   157,   157,   159,   159,   159,   159,   159,   159,   159,
+     159,   160,   160,   160,   161,   161,   161,   161,   161,   161,
+     162,   163,   163,   164,   164,   166,   165,   167,   167,   167,
+     167,   167,   167,   167,   167,   167,   167,   167,   168,   168,
+     169,   169,   170,   170,   170,   170,   170,   170,   170,   170,
+     170,   170,   171,   171,   172,   172,   173,   173,   174,   174,
+     174,   174,   174,   174,   174,   174,   175,   175,   175,   175,
+     175,   175,   175,   175,   175,   176,   176,   177,   177,   177,
+     178,   178,   178,   178,   178,   179,   179,   180,   181,   180,
+     182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
+     182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
+     182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
+     183,   183,   183,   183,   183,   183,   183,   183,   183,   183,
+     183,   183,   183,   183,   183,   183,   183,   183,   183,   183,
+     183,   183,   183,   183,   183,   183,   183,   183,   183,   183,
+     183,   183,   183,   183,   183,   183,   183,   183,   183,   183,
+     184,   184,   184,   184,   184,   184,   184,   184,   184,   184,
+     184,   184,   184,   184,   184,   184,   184,   184,   184,   184,
+     184,   184,   184,   184,   184,   184,   184,   184,   184,   184,
+     184,   184,   184,   184,   184,   184,   184,   184,   184,   184,
+     184,   184,   184,   185,   185,   185,   185,   186,   186,   187,
+     187,   188,   188,   189,   189,   189,   189,   189,   190,   190,
+     190,   190,   190,   192,   191,   193,   194,   194,   195,   195,
+     196,   196,   196,   196,   197,   197,   197,   198,   198,   198,
+     198,   198,   198,   198,   198,   198,   199,   198,   200,   201,
+     198,   202,   198,   198,   198,   198,   198,   198,   198,   198,
+     198,   198,   198,   198,   198,   203,   204,   198,   198,   198,
+     205,   206,   198,   207,   208,   198,   198,   198,   209,   210,
+     198,   211,   198,   212,   213,   198,   214,   198,   215,   216,
+     198,   217,   218,   198,   198,   198,   198,   198,   219,   220,
+     220,   220,   221,   221,   222,   222,   223,   223,   224,   224,
+     225,   225,   225,   225,   225,   225,   225,   225,   226,   225,
+     227,   227,   227,   227,   228,   228,   229,   229,   229,   229,
+     229,   229,   229,   229,   229,   229,   229,   229,   229,   229,
+     229,   230,   230,   232,   231,   231,   231,   233,   233,   234,
+     234,   235,   235,   236,   236,   237,   237,   239,   238,   240,
+     240,   240,   240,   241,   241,   241,   241,   241,   241,   241,
+     241,   241,   243,   242,   244,   242,   245,   246,   246,   247,
+     247,   248,   248,   248,   249,   249,   250,   250,   251,   251,
+     251,   251,   252,   252,   253,   253,   253,   253,   254,   254,
+     255,   256,   255,   255,   255,   257,   257,   258,   258,   259,
+     260,   260,   261,   261,   262,   262,   263,   264,   263,   265,
+     265,   266,   266,   267,   268,   268,   268,   268,   268,   268,
+     269,   269,   270,   270,   270,   270,   271,   271,   271,   271,
+     271,   272,   272,   273,   273,   273,   273,   273,   273,   273,
+     273,   274,   274,   275,   276,   275,   277,   277,   277,   278,
+     279,   279,   280,   280,   281,   281,   282,   282,   283,   283,
+     284,   284,   285,   285,   285,   285,   286,   286,   287,   287,
+     287,   287,   287,   287,   287,   287,   287,   287,   287,   287,
+     287,   287,   287,   288,   288,   288,   288,   288,   289,   289,
+     290,   291,   290,   292,   292,   293,   294,   295,   296,   296,
+     297,   297,   298,   298,   299,   299,   300,   300,   301,   302,
+     302,   303,   304,   303,   305,   305,   306,   306,   307,   307,
+     308,   308,   308,   308,   309,   309,   309,   310,   310,   310,
+     310,   311,   311,   311,   312,   312,   313,   313,   314,   314,
+     315,   315,   316,   316,   317,   318,   318,   318,   319,   319,
+     319,   320,   321,   321,   322
+};
+
+  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
+static const yytype_int8 yyr2[] =
+{
+       0,     2,     0,     2,     2,     1,     1,     3,     2,     1,
+       0,     5,     4,     2,     1,     1,     3,     2,     0,     4,
+       2,     3,     3,     3,     3,     3,     4,     1,     3,     3,
+       3,     3,     1,     3,     3,     6,     5,     5,     5,     5,
+       3,     1,     3,     1,     1,     3,     3,     3,     2,     1,
+       1,     1,     1,     1,     4,     0,     5,     2,     3,     4,
+       5,     4,     5,     2,     2,     2,     2,     2,     1,     3,
+       1,     3,     1,     2,     3,     5,     2,     4,     2,     4,
+       1,     3,     1,     3,     2,     3,     1,     2,     1,     4,
+       3,     3,     3,     3,     2,     1,     1,     4,     3,     3,
+       3,     3,     2,     1,     1,     1,     1,     2,     1,     3,
+       1,     1,     1,     1,     1,     1,     1,     1,     0,     4,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       3,     3,     6,     5,     5,     5,     5,     4,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     4,     4,     2,
+       2,     3,     3,     3,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     2,     2,     3,     3,     3,     3,
+       6,     6,     1,     1,     2,     4,     2,     1,     3,     3,
+       3,     1,     1,     1,     2,     2,     4,     2,     1,     2,
+       2,     4,     1,     0,     2,     2,     2,     1,     1,     3,
+       1,     2,     3,     4,     3,     4,     2,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     0,     4,     0,     0,
+       5,     0,     3,     3,     3,     2,     3,     3,     1,     2,
+       4,     3,     2,     1,     2,     0,     0,     5,     6,     6,
+       0,     0,     7,     0,     0,     7,     5,     4,     0,     0,
+       9,     0,     6,     0,     0,     8,     0,     5,     0,     0,
+       7,     0,     0,     9,     1,     1,     1,     1,     1,     1,
+       1,     2,     1,     1,     1,     5,     1,     2,     1,     1,
+       1,     4,     6,     3,     5,     2,     4,     1,     0,     4,
+       4,     2,     2,     1,     2,     0,     6,     8,     4,     6,
+       4,     3,     6,     2,     4,     6,     2,     4,     2,     4,
+       1,     1,     1,     0,     4,     1,     4,     1,     4,     1,
+       3,     1,     1,     4,     1,     3,     3,     0,     5,     2,
+       4,     5,     5,     2,     4,     4,     3,     3,     3,     2,
+       1,     4,     0,     5,     0,     5,     5,     1,     1,     6,
+       1,     1,     1,     1,     2,     1,     2,     1,     1,     1,
+       1,     1,     1,     2,     1,     1,     2,     3,     1,     2,
+       1,     0,     4,     1,     2,     2,     3,     2,     3,     1,
+       1,     2,     1,     2,     1,     2,     1,     0,     4,     2,
+       3,     1,     4,     2,     1,     1,     1,     1,     1,     2,
+       2,     3,     1,     1,     2,     2,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     0,     0,     4,     3,     3,     2,     2,
+       2,     1,     2,     1,     1,     3,     1,     3,     1,     1,
+       2,     1,     4,     2,     2,     1,     2,     0,     6,     8,
+       4,     6,     4,     6,     2,     4,     6,     2,     4,     2,
+       4,     1,     0,     1,     1,     1,     1,     1,     1,     1,
+       1,     0,     4,     1,     3,     2,     2,     2,     1,     3,
+       1,     3,     1,     1,     2,     1,     1,     1,     2,     2,
+       1,     1,     0,     4,     1,     2,     1,     3,     1,     2,
+       3,     3,     3,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       0,     1,     0,     1,     2,     0,     1,     1,     1,     1,
+       1,     1,     1,     2,     0
+};
+
+
+#define yyerrok         (yyerrstatus = 0)
+#define yyclearin       (yychar = YYEMPTY)
+#define YYEMPTY         (-2)
+#define YYEOF           0
+
+#define YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
+
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                    \
+  do                                                              \
+    if (yychar == YYEMPTY)                                        \
+      {                                                           \
+        yychar = (Token);                                         \
+        yylval = (Value);                                         \
+        YYPOPSTACK (yylen);                                       \
+        yystate = *yyssp;                                         \
+        goto yybackup;                                            \
+      }                                                           \
+    else                                                          \
+      {                                                           \
+        yyerror (p, YY_("syntax error: cannot back up")); \
+        YYERROR;                                                  \
+      }                                                           \
+  while (0)
+
+/* Error token number */
+#define YYTERROR        1
+#define YYERRCODE       256
+
+
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                        \
+do {                                            \
+  if (yydebug)                                  \
+    YYFPRINTF Args;                             \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
+do {                                                                      \
+  if (yydebug)                                                            \
+    {                                                                     \
+      YYFPRINTF (stderr, "%s ", Title);                                   \
+      yy_symbol_print (stderr,                                            \
+                  Type, Value, p); \
+      YYFPRINTF (stderr, "\n");                                           \
+    }                                                                     \
+} while (0)
+
+
+/*-----------------------------------.
+| Print this symbol's value on YYO.  |
+`-----------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, parser_state *p)
+{
+  FILE *yyoutput = yyo;
+  YYUSE (yyoutput);
+  YYUSE (p);
+  if (!yyvaluep)
+    return;
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
+# endif
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  YYUSE (yytype);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+/*---------------------------.
+| Print this symbol on YYO.  |
+`---------------------------*/
+
+static void
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, parser_state *p)
+{
+  YYFPRINTF (yyo, "%s %s (",
+             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+  yy_symbol_value_print (yyo, yytype, yyvaluep, p);
+  YYFPRINTF (yyo, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                            \
+do {                                                            \
+  if (yydebug)                                                  \
+    yy_stack_print ((Bottom), (Top));                           \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule, parser_state *p)
+{
+  int yylno = yyrline[yyrule];
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
+             yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr,
+                       yystos[+yyssp[yyi + 1 - yynrhs]],
+                       &yyvsp[(yyi + 1) - (yynrhs)]
+                                              , p);
+      YYFPRINTF (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)          \
+do {                                    \
+  if (yydebug)                          \
+    yy_reduce_print (yyssp, yyvsp, Rule, p); \
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
+#  else
+/* Return the length of YYSTR.  */
+static YYPTRDIFF_T
+yystrlen (const char *yystr)
+{
+  YYPTRDIFF_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYPTRDIFF_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYPTRDIFF_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+        switch (*++yyp)
+          {
+          case '\'':
+          case ',':
+            goto do_not_strip_quotes;
+
+          case '\\':
+            if (*++yyp != '\\')
+              goto do_not_strip_quotes;
+            else
+              goto append;
+
+          append:
+          default:
+            if (yyres)
+              yyres[yyn] = *yyp;
+            yyn++;
+            break;
+
+          case '"':
+            if (yyres)
+              yyres[yyn] = '\0';
+            return yyn;
+          }
+    do_not_strip_quotes: ;
+    }
+
+  if (yyres)
+    return yystpcpy (yyres, yystr) - yyres;
+  else
+    return yystrlen (yystr);
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
+
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
+                yy_state_t *yyssp, int yytoken)
+{
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULLPTR;
+  /* Arguments of yyformat: reported tokens (one for the "unexpected",
+     one per "expected"). */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Actual size of YYARG. */
+  int yycount = 0;
+  /* Cumulated lengths of YYARG.  */
+  YYPTRDIFF_T yysize = 0;
+
+  /* There are many possibilities here to consider:
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
+    {
+      int yyn = yypact[+*yyssp];
+      YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+      yysize = yysize0;
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          int yyxbegin = yyn < 0 ? -yyn : 0;
+          /* Stay within bounds of both yycheck and yytname.  */
+          int yychecklim = YYLAST - yyn + 1;
+          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+          int yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                {
+                  YYPTRDIFF_T yysize1
+                    = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+                  if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+                    yysize = yysize1;
+                  else
+                    return 2;
+                }
+              }
+        }
+    }
+
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+    default: /* Avoid compiler warnings. */
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
+
+  {
+    /* Don't count the "%s"s in the final size, but reserve room for
+       the terminator.  */
+    YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1;
+    if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+      yysize = yysize1;
+    else
+      return 2;
+  }
+
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
+    }
+
+  /* Avoid sprintf, as that infringes on the user's name space.
+     Don't have undefined behavior even if the translation
+     produced a string with the wrong number of "%s"s.  */
+  {
+    char *yyp = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          ++yyp;
+          ++yyformat;
+        }
+  }
+  return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, parser_state *p)
+{
+  YYUSE (yyvaluep);
+  YYUSE (p);
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  YYUSE (yytype);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+int
+yyparse (parser_state *p)
+{
+/* The lookahead symbol.  */
+int yychar;
+
+
+/* The semantic value of the lookahead symbol.  */
+/* Default value used for initialization, for pacifying older GCCs
+   or non-GCC compilers.  */
+YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
+YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
+
+    /* Number of syntax errors so far.  */
+    int yynerrs;
+
+    yy_state_fast_t yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       'yyss': related to states.
+       'yyvs': related to semantic values.
+
+       Refer to the stacks through separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yy_state_t yyssa[YYINITDEPTH];
+    yy_state_t *yyss;
+    yy_state_t *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
+
+    YYPTRDIFF_T yystacksize;
+
+  int yyn;
+  int yyresult;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
+  yystacksize = YYINITDEPTH;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY; /* Cause a token to be read.  */
+  goto yysetstate;
+
+
+/*------------------------------------------------------------.
+| yynewstate -- push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+
+/*--------------------------------------------------------------------.
+| yysetstate -- set current state (the top of the stack) to yystate.  |
+`--------------------------------------------------------------------*/
+yysetstate:
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+  YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
+  YY_IGNORE_USELESS_CAST_BEGIN
+  *yyssp = YY_CAST (yy_state_t, yystate);
+  YY_IGNORE_USELESS_CAST_END
+
+  if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+    goto yyexhaustedlab;
+#else
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYPTRDIFF_T yysize = yyssp - yyss + 1;
+
+# if defined yyoverflow
+      {
+        /* Give user a chance to reallocate the stack.  Use copies of
+           these so that the &'s don't force the real ones into
+           memory.  */
+        yy_state_t *yyss1 = yyss;
+        YYSTYPE *yyvs1 = yyvs;
+
+        /* Each stack pointer address is followed by the size of the
+           data in use in that stack, in bytes.  This used to be a
+           conditional around just the two extra args, but that might
+           be undefined if yyoverflow is a macro.  */
+        yyoverflow (YY_("memory exhausted"),
+                    &yyss1, yysize * YYSIZEOF (*yyssp),
+                    &yyvs1, yysize * YYSIZEOF (*yyvsp),
+                    &yystacksize);
+        yyss = yyss1;
+        yyvs = yyvs1;
+      }
+# else /* defined YYSTACK_RELOCATE */
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+        goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+        yystacksize = YYMAXDEPTH;
+
+      {
+        yy_state_t *yyss1 = yyss;
+        union yyalloc *yyptr =
+          YY_CAST (union yyalloc *,
+                   YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
+        if (! yyptr)
+          goto yyexhaustedlab;
+        YYSTACK_RELOCATE (yyss_alloc, yyss);
+        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+        if (yyss1 != yyssa)
+          YYSTACK_FREE (yyss1);
+      }
+# endif
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+      YY_IGNORE_USELESS_CAST_BEGIN
+      YYDPRINTF ((stderr, "Stack size increased to %ld\n",
+                  YY_CAST (long, yystacksize)));
+      YY_IGNORE_USELESS_CAST_END
+
+      if (yyss + yystacksize - 1 <= yyssp)
+        YYABORT;
+    }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
+  goto yybackup;
+
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+  /* Do appropriate processing given the current state.  Read a
+     lookahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+  yyn = yypact[yystate];
+  if (yypact_value_is_default (yyn))
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = yylex (&yylval, p);
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the lookahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+  yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     '$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+  case 2:
+#line 1508 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->lstate = EXPR_BEG;
+                      if (!p->locals) p->locals = cons(0,0);
+                    }
+#line 5675 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 3:
+#line 1513 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->tree = new_scope(p, (yyvsp[0].nd));
+                      NODE_LINENO(p->tree, (yyvsp[0].nd));
+                    }
+#line 5684 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 4:
+#line 1520 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 5692 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 5:
+#line 1526 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_begin(p, 0);
+                    }
+#line 5700 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 6:
+#line 1530 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_begin(p, (yyvsp[0].nd));
+                      NODE_LINENO((yyval.nd), (yyvsp[0].nd));
+                    }
+#line 5709 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 7:
+#line 1535 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd)));
+                    }
+#line 5717 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 8:
+#line 1539 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_begin(p, 0);
+                    }
+#line 5725 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 10:
+#line 1546 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = local_switch(p);
+                      nvars_block(p);
+                    }
+#line 5734 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 11:
+#line 1551 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "BEGIN not supported");
+                      local_resume(p, (yyvsp[-3].nd));
+                      nvars_unnest(p);
+                      (yyval.nd) = 0;
+                    }
+#line 5745 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 12:
+#line 1563 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if ((yyvsp[-2].nd)) {
+                        (yyval.nd) = new_rescue(p, (yyvsp[-3].nd), (yyvsp[-2].nd), (yyvsp[-1].nd));
+                        NODE_LINENO((yyval.nd), (yyvsp[-3].nd));
+                      }
+                      else if ((yyvsp[-1].nd)) {
+                        yywarn(p, "else without rescue is useless");
+                        (yyval.nd) = push((yyvsp[-3].nd), (yyvsp[-1].nd));
+                      }
+                      else {
+                        (yyval.nd) = (yyvsp[-3].nd);
+                      }
+                      if ((yyvsp[0].nd)) {
+                        if ((yyval.nd)) {
+                          (yyval.nd) = new_ensure(p, (yyval.nd), (yyvsp[0].nd));
+                        }
+                        else {
+                          (yyval.nd) = push((yyvsp[0].nd), new_nil(p));
+                        }
+                      }
+                    }
+#line 5771 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 13:
+#line 1587 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 5779 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 14:
+#line 1593 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_begin(p, 0);
+                    }
+#line 5787 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 15:
+#line 1597 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_begin(p, (yyvsp[0].nd));
+                      NODE_LINENO((yyval.nd), (yyvsp[0].nd));
+                    }
+#line 5796 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 16:
+#line 1602 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd)));
+                    }
+#line 5804 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 17:
+#line 1606 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_begin(p, (yyvsp[0].nd));
+                    }
+#line 5812 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 18:
+#line 1611 "mrbgems/mruby-compiler/core/parse.y"
+                                     {p->lstate = EXPR_FNAME;}
+#line 5818 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 19:
+#line 1612 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_alias(p, (yyvsp[-2].id), (yyvsp[0].id));
+                    }
+#line 5826 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 20:
+#line 1616 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 5834 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 21:
+#line 1620 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_if(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0);
+                    }
+#line 5842 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 22:
+#line 1624 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_unless(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0);
+                    }
+#line 5850 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 23:
+#line 1628 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_while(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd));
+                    }
+#line 5858 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 24:
+#line 1632 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_until(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd));
+                    }
+#line 5866 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 25:
+#line 1636 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 5874 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 26:
+#line 1640 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "END not supported");
+                      (yyval.nd) = new_postexe(p, (yyvsp[-1].nd));
+                    }
+#line 5883 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 28:
+#line 1646 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 5891 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 29:
+#line 1650 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd)));
+                    }
+#line 5899 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 30:
+#line 1654 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 5907 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 31:
+#line 1658 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd)));
+                    }
+#line 5915 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 33:
+#line 1665 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 5923 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 34:
+#line 1669 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 5931 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 35:
+#line 1673 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-5].nd), intern_lit("[]"), (yyvsp[-3].nd), '.'), (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 5939 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 36:
+#line 1677 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 5947 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 37:
+#line 1681 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 5955 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 38:
+#line 1685 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "constant re-assignment");
+                      (yyval.nd) = 0;
+                    }
+#line 5964 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 39:
+#line 1690 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, tCOLON2), (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 5972 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 40:
+#line 1694 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      backref_error(p, (yyvsp[-2].nd));
+                      (yyval.nd) = new_begin(p, 0);
+                    }
+#line 5981 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 42:
+#line 1702 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 5989 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 45:
+#line 1711 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 5997 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 46:
+#line 1715 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 6005 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 47:
+#line 1719 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!");
+                    }
+#line 6013 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 48:
+#line 1723 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!");
+                    }
+#line 6021 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 50:
+#line 1730 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if (!(yyvsp[0].nd)) (yyval.nd) = new_nil(p);
+                      else {
+                        (yyval.nd) = (yyvsp[0].nd);
+                      }
+                    }
+#line 6032 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 54:
+#line 1744 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num));
+                    }
+#line 6040 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 55:
+#line 1750 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_nest(p);
+                      nvars_nest(p);
+                    }
+#line 6049 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 56:
+#line 1757 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_block(p, (yyvsp[-2].nd), (yyvsp[-1].nd));
+                      local_unnest(p);
+                      nvars_unnest(p);
+                    }
+#line 6059 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 57:
+#line 1765 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 6067 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 58:
+#line 1769 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd));
+                      (yyval.nd) = new_fcall(p, (yyvsp[-2].id), (yyvsp[-1].nd));
+                    }
+#line 6076 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 59:
+#line 1774 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num));
+                    }
+#line 6084 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 60:
+#line 1778 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd));
+                      (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), (yyvsp[-3].num));
+                   }
+#line 6093 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 61:
+#line 1783 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2);
+                    }
+#line 6101 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 62:
+#line 1787 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd));
+                      (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), tCOLON2);
+                    }
+#line 6110 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 63:
+#line 1792 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_super(p, (yyvsp[0].nd));
+                    }
+#line 6118 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 64:
+#line 1796 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_yield(p, (yyvsp[0].nd));
+                    }
+#line 6126 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 65:
+#line 1800 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_return(p, ret_args(p, (yyvsp[0].nd)));
+                    }
+#line 6134 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 66:
+#line 1804 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_break(p, ret_args(p, (yyvsp[0].nd)));
+                    }
+#line 6142 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 67:
+#line 1808 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_next(p, ret_args(p, (yyvsp[0].nd)));
+                    }
+#line 6150 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 68:
+#line 1814 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 6158 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 69:
+#line 1818 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 6166 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 71:
+#line 1825 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 6174 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 72:
+#line 1831 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1((yyvsp[0].nd));
+                    }
+#line 6182 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 73:
+#line 1835 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1(push((yyvsp[-1].nd),(yyvsp[0].nd)));
+                    }
+#line 6190 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 74:
+#line 1839 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list2((yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 6198 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 75:
+#line 1843 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3((yyvsp[-4].nd), (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 6206 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 76:
+#line 1847 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list2((yyvsp[-1].nd), new_nil(p));
+                    }
+#line 6214 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 77:
+#line 1851 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3((yyvsp[-3].nd), new_nil(p), (yyvsp[0].nd));
+                    }
+#line 6222 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 78:
+#line 1855 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list2(0, (yyvsp[0].nd));
+                    }
+#line 6230 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 79:
+#line 1859 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3(0, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 6238 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 80:
+#line 1863 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list2(0, new_nil(p));
+                    }
+#line 6246 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 81:
+#line 1867 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3(0, new_nil(p), (yyvsp[0].nd));
+                    }
+#line 6254 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 83:
+#line 1874 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_masgn(p, (yyvsp[-1].nd), NULL);
+                    }
+#line 6262 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 84:
+#line 1880 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1((yyvsp[-1].nd));
+                    }
+#line 6270 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 85:
+#line 1884 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[-1].nd));
+                    }
+#line 6278 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 86:
+#line 1890 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1((yyvsp[0].nd));
+                    }
+#line 6286 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 87:
+#line 1894 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 6294 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 88:
+#line 1900 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      assignable(p, (yyvsp[0].nd));
+                    }
+#line 6302 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 89:
+#line 1904 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_lit("[]"), (yyvsp[-1].nd), '.');
+                    }
+#line 6310 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 90:
+#line 1908 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num));
+                    }
+#line 6318 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 91:
+#line 1912 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2);
+                    }
+#line 6326 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 92:
+#line 1916 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num));
+                    }
+#line 6334 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 93:
+#line 1920 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "dynamic constant assignment");
+                      (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id));
+                    }
+#line 6344 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 94:
+#line 1926 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "dynamic constant assignment");
+                      (yyval.nd) = new_colon3(p, (yyvsp[0].id));
+                    }
+#line 6354 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 95:
+#line 1932 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      backref_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = 0;
+                    }
+#line 6363 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 96:
+#line 1939 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      assignable(p, (yyvsp[0].nd));
+                    }
+#line 6371 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 97:
+#line 1943 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_lit("[]"), (yyvsp[-1].nd), '.');
+                    }
+#line 6379 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 98:
+#line 1947 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num));
+                    }
+#line 6387 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 99:
+#line 1951 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2);
+                    }
+#line 6395 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 100:
+#line 1955 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num));
+                    }
+#line 6403 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 101:
+#line 1959 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "dynamic constant assignment");
+                      (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id));
+                    }
+#line 6413 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 102:
+#line 1965 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "dynamic constant assignment");
+                      (yyval.nd) = new_colon3(p, (yyvsp[0].id));
+                    }
+#line 6423 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 103:
+#line 1971 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      backref_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = 0;
+                    }
+#line 6432 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 104:
+#line 1976 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "can't assign to numbered parameter");
+                    }
+#line 6440 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 105:
+#line 1982 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "class/module name must be CONSTANT");
+                    }
+#line 6448 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 107:
+#line 1989 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons((node*)1, nsym((yyvsp[0].id)));
+                    }
+#line 6456 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 108:
+#line 1993 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons((node*)0, nsym((yyvsp[0].id)));
+                    }
+#line 6464 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 109:
+#line 1997 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[-2].nd));
+                      (yyval.nd) = cons((yyvsp[-2].nd), nsym((yyvsp[0].id)));
+                    }
+#line 6473 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 113:
+#line 2007 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->lstate = EXPR_ENDFN;
+                      (yyval.id) = (yyvsp[0].id);
+                    }
+#line 6482 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 114:
+#line 2012 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->lstate = EXPR_ENDFN;
+                      (yyval.id) = (yyvsp[0].id);
+                    }
+#line 6491 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 117:
+#line 2023 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_undef(p, (yyvsp[0].id));
+                    }
+#line 6499 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 118:
+#line 2026 "mrbgems/mruby-compiler/core/parse.y"
+                                 {p->lstate = EXPR_FNAME;}
+#line 6505 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 119:
+#line 2027 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-3].nd), nsym((yyvsp[0].id)));
+                    }
+#line 6513 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 120:
+#line 2032 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("|");   }
+#line 6519 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 121:
+#line 2033 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("^");   }
+#line 6525 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 122:
+#line 2034 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("&");   }
+#line 6531 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 123:
+#line 2035 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("<=>"); }
+#line 6537 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 124:
+#line 2036 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("==");  }
+#line 6543 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 125:
+#line 2037 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("==="); }
+#line 6549 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 126:
+#line 2038 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("=~");  }
+#line 6555 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 127:
+#line 2039 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("!~");  }
+#line 6561 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 128:
+#line 2040 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit(">");   }
+#line 6567 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 129:
+#line 2041 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit(">=");  }
+#line 6573 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 130:
+#line 2042 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("<");   }
+#line 6579 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 131:
+#line 2043 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("<=");  }
+#line 6585 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 132:
+#line 2044 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("!=");  }
+#line 6591 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 133:
+#line 2045 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("<<");  }
+#line 6597 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 134:
+#line 2046 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit(">>");  }
+#line 6603 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 135:
+#line 2047 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("+");   }
+#line 6609 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 136:
+#line 2048 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("-");   }
+#line 6615 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 137:
+#line 2049 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("*");   }
+#line 6621 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 138:
+#line 2050 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("*");   }
+#line 6627 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 139:
+#line 2051 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("/");   }
+#line 6633 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 140:
+#line 2052 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("%");   }
+#line 6639 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 141:
+#line 2053 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("**");  }
+#line 6645 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 142:
+#line 2054 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("**");  }
+#line 6651 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 143:
+#line 2055 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("!");   }
+#line 6657 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 144:
+#line 2056 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("~");   }
+#line 6663 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 145:
+#line 2057 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("+@");  }
+#line 6669 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 146:
+#line 2058 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("-@");  }
+#line 6675 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 147:
+#line 2059 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("[]");  }
+#line 6681 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 148:
+#line 2060 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("[]="); }
+#line 6687 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 149:
+#line 2061 "mrbgems/mruby-compiler/core/parse.y"
+                                { (yyval.id) = intern_lit("`");   }
+#line 6693 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 190:
+#line 2079 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 6701 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 191:
+#line 2083 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 6709 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 192:
+#line 2087 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-5].nd), intern_lit("[]"), (yyvsp[-3].nd), '.'), (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 6717 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 193:
+#line 2091 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 6725 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 194:
+#line 2095 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 6733 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 195:
+#line 2099 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, tCOLON2), (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 6741 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 196:
+#line 2103 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "constant re-assignment");
+                      (yyval.nd) = new_begin(p, 0);
+                    }
+#line 6750 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 197:
+#line 2108 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "constant re-assignment");
+                      (yyval.nd) = new_begin(p, 0);
+                    }
+#line 6759 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 198:
+#line 2113 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      backref_error(p, (yyvsp[-2].nd));
+                      (yyval.nd) = new_begin(p, 0);
+                    }
+#line 6768 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 199:
+#line 2118 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_dot2(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 6776 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 200:
+#line 2122 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_dot3(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 6784 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 201:
+#line 2126 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "+", (yyvsp[0].nd));
+                    }
+#line 6792 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 202:
+#line 2130 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "-", (yyvsp[0].nd));
+                    }
+#line 6800 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 203:
+#line 2134 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "*", (yyvsp[0].nd));
+                    }
+#line 6808 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 204:
+#line 2138 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "/", (yyvsp[0].nd));
+                    }
+#line 6816 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 205:
+#line 2142 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "%", (yyvsp[0].nd));
+                    }
+#line 6824 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 206:
+#line 2146 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd));
+                    }
+#line 6832 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 207:
+#line 2150 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_uni_op(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)), "-@");
+                    }
+#line 6840 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 208:
+#line 2154 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_uni_op(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)), "-@");
+                    }
+#line 6848 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 209:
+#line 2158 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_uni_op(p, (yyvsp[0].nd), "+@");
+                    }
+#line 6856 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 210:
+#line 2162 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_uni_op(p, (yyvsp[0].nd), "-@");
+                    }
+#line 6864 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 211:
+#line 2166 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "|", (yyvsp[0].nd));
+                    }
+#line 6872 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 212:
+#line 2170 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "^", (yyvsp[0].nd));
+                    }
+#line 6880 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 213:
+#line 2174 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "&", (yyvsp[0].nd));
+                    }
+#line 6888 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 214:
+#line 2178 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=>", (yyvsp[0].nd));
+                    }
+#line 6896 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 215:
+#line 2182 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">", (yyvsp[0].nd));
+                    }
+#line 6904 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 216:
+#line 2186 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">=", (yyvsp[0].nd));
+                    }
+#line 6912 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 217:
+#line 2190 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<", (yyvsp[0].nd));
+                    }
+#line 6920 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 218:
+#line 2194 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=", (yyvsp[0].nd));
+                    }
+#line 6928 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 219:
+#line 2198 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "==", (yyvsp[0].nd));
+                    }
+#line 6936 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 220:
+#line 2202 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "===", (yyvsp[0].nd));
+                    }
+#line 6944 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 221:
+#line 2206 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!=", (yyvsp[0].nd));
+                    }
+#line 6952 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 222:
+#line 2210 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "=~", (yyvsp[0].nd));
+                    }
+#line 6960 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 223:
+#line 2214 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!~", (yyvsp[0].nd));
+                    }
+#line 6968 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 224:
+#line 2218 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!");
+                    }
+#line 6976 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 225:
+#line 2222 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "~");
+                    }
+#line 6984 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 226:
+#line 2226 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<<", (yyvsp[0].nd));
+                    }
+#line 6992 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 227:
+#line 2230 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">>", (yyvsp[0].nd));
+                    }
+#line 7000 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 228:
+#line 2234 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 7008 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 229:
+#line 2238 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 7016 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 230:
+#line 2242 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd));
+                    }
+#line 7024 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 231:
+#line 2246 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd));
+                    }
+#line 7032 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 232:
+#line 2250 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 7040 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 234:
+#line 2257 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                      NODE_LINENO((yyval.nd), (yyvsp[-1].nd));
+                    }
+#line 7049 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 235:
+#line 2262 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-3].nd), new_kw_hash(p, (yyvsp[-1].nd)));
+                    }
+#line 7057 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 236:
+#line 2266 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons(new_kw_hash(p, (yyvsp[-1].nd)), 0);
+                      NODE_LINENO((yyval.nd), (yyvsp[-1].nd));
+                    }
+#line 7066 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 237:
+#line 2273 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 7074 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 238:
+#line 2277 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[-2].nd));
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 7084 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 239:
+#line 2285 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 7092 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 240:
+#line 2289 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+#if 1
+                      mrb_sym r = mrb_intern_lit(p->mrb, "*");
+                      mrb_sym b = mrb_intern_lit(p->mrb, "&");
+                      if (local_var_p(p, r)  && local_var_p(p, b)) {
+                        (yyval.nd) = cons(list1(new_splat(p, new_lvar(p, r))),
+                                  new_block_arg(p, new_lvar(p, b)));
+                      }
+#else
+                      mrb_sym r = mrb_intern_lit(p->mrb, "*");
+                      mrb_sym k = mrb_intern_lit(p->mrb, "**");
+                      mrb_sym b = mrb_intern_lit(p->mrb, "&");
+                      if (local_var_p(p, r) && local_var_p(p, k) && local_var_p(p, b)) {
+                        (yyval.nd) = cons(list2(new_splat(p, new_lvar(p, r)),
+                                        new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))),
+                                  new_block_arg(p, new_lvar(p, b)));
+                      }
+#endif
+                      else {
+                        yyerror(p, "unexpected argument forwarding ...");
+                        (yyval.nd) = 0;
+                      }
+                    }
+#line 7120 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 245:
+#line 2321 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons((yyvsp[-1].nd),0);
+                      NODE_LINENO((yyval.nd), (yyvsp[-1].nd));
+                    }
+#line 7129 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 246:
+#line 2326 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons(push((yyvsp[-3].nd), new_kw_hash(p, (yyvsp[-1].nd))), 0);
+                      NODE_LINENO((yyval.nd), (yyvsp[-3].nd));
+                    }
+#line 7138 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 247:
+#line 2331 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons(list1(new_kw_hash(p, (yyvsp[-1].nd))), 0);
+                      NODE_LINENO((yyval.nd), (yyvsp[-1].nd));
+                    }
+#line 7147 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 248:
+#line 2338 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = cons(list1((yyvsp[0].nd)), 0);
+                      NODE_LINENO((yyval.nd), (yyvsp[0].nd));
+                    }
+#line 7157 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 249:
+#line 2344 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons((yyvsp[-1].nd), (yyvsp[0].nd));
+                      NODE_LINENO((yyval.nd), (yyvsp[-1].nd));
+                    }
+#line 7166 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 250:
+#line 2349 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons(list1(new_kw_hash(p, (yyvsp[-1].nd))), (yyvsp[0].nd));
+                      NODE_LINENO((yyval.nd), (yyvsp[-1].nd));
+                    }
+#line 7175 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 251:
+#line 2354 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons(push((yyvsp[-3].nd), new_kw_hash(p, (yyvsp[-1].nd))), (yyvsp[0].nd));
+                      NODE_LINENO((yyval.nd), (yyvsp[-3].nd));
+                    }
+#line 7184 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 252:
+#line 2359 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons(0, (yyvsp[0].nd));
+                      NODE_LINENO((yyval.nd), (yyvsp[0].nd));
+                    }
+#line 7193 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 253:
+#line 2365 "mrbgems/mruby-compiler/core/parse.y"
+                   {
+                      (yyval.stack) = p->cmdarg_stack;
+                      CMDARG_PUSH(1);
+                    }
+#line 7202 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 254:
+#line 2370 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->cmdarg_stack = (yyvsp[-1].stack);
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 7211 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 255:
+#line 2377 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_block_arg(p, (yyvsp[0].nd));
+                    }
+#line 7219 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 256:
+#line 2383 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 7227 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 257:
+#line 2387 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = 0;
+                    }
+#line 7235 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 260:
+#line 2397 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = cons((yyvsp[0].nd), 0);
+                      NODE_LINENO((yyval.nd), (yyvsp[0].nd));
+                    }
+#line 7245 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 261:
+#line 2403 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = cons(new_splat(p, (yyvsp[0].nd)), 0);
+                      NODE_LINENO((yyval.nd), (yyvsp[0].nd));
+                    }
+#line 7255 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 262:
+#line 2409 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 7264 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 263:
+#line 2414 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd)));
+                    }
+#line 7273 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 264:
+#line 2421 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 7282 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 265:
+#line 2426 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd)));
+                    }
+#line 7291 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 266:
+#line 2431 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd)));
+                    }
+#line 7300 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 274:
+#line 2445 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_nvar(p, (yyvsp[0].num));
+                    }
+#line 7308 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 275:
+#line 2449 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_fcall(p, (yyvsp[0].id), 0);
+                    }
+#line 7316 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 276:
+#line 2453 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.stack) = p->cmdarg_stack;
+                      p->cmdarg_stack = 0;
+                    }
+#line 7325 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 277:
+#line 2459 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->cmdarg_stack = (yyvsp[-2].stack);
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 7334 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 278:
+#line 2464 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.stack) = p->cmdarg_stack;
+                      p->cmdarg_stack = 0;
+                    }
+#line 7343 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 279:
+#line 2468 "mrbgems/mruby-compiler/core/parse.y"
+                       {p->lstate = EXPR_ENDARG;}
+#line 7349 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 280:
+#line 2469 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->cmdarg_stack = (yyvsp[-3].stack);
+                      (yyval.nd) = (yyvsp[-2].nd);
+                    }
+#line 7358 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 281:
+#line 2473 "mrbgems/mruby-compiler/core/parse.y"
+                              {p->lstate = EXPR_ENDARG;}
+#line 7364 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 282:
+#line 2474 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_nil(p);
+                    }
+#line 7372 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 283:
+#line 2478 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 7380 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 284:
+#line 2482 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id));
+                    }
+#line 7388 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 285:
+#line 2486 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_colon3(p, (yyvsp[0].id));
+                    }
+#line 7396 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 286:
+#line 2490 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_array(p, (yyvsp[-1].nd));
+                      NODE_LINENO((yyval.nd), (yyvsp[-1].nd));
+                    }
+#line 7405 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 287:
+#line 2495 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_hash(p, (yyvsp[-1].nd));
+                      NODE_LINENO((yyval.nd), (yyvsp[-1].nd));
+                    }
+#line 7414 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 288:
+#line 2500 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_return(p, 0);
+                    }
+#line 7422 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 289:
+#line 2504 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_yield(p, (yyvsp[0].nd));
+                    }
+#line 7430 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 290:
+#line 2508 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_uni_op(p, cond((yyvsp[-1].nd)), "!");
+                    }
+#line 7438 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 291:
+#line 2512 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = call_uni_op(p, new_nil(p), "!");
+                    }
+#line 7446 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 292:
+#line 2516 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_fcall(p, (yyvsp[-1].id), cons(0, (yyvsp[0].nd)));
+                    }
+#line 7454 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 294:
+#line 2521 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      call_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd));
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 7463 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 295:
+#line 2526 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_nest(p);
+                      (yyval.num) = p->lpar_beg;
+                      p->lpar_beg = ++p->paren_nest;
+                    }
+#line 7473 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 296:
+#line 2532 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.stack) = p->cmdarg_stack;
+                      p->cmdarg_stack = 0;
+                    }
+#line 7482 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 297:
+#line 2537 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->lpar_beg = (yyvsp[-3].num);
+                      (yyval.nd) = new_lambda(p, (yyvsp[-2].nd), (yyvsp[0].nd));
+                      local_unnest(p);
+                      p->cmdarg_stack = (yyvsp[-1].stack);
+                      CMDARG_LEXPOP();
+                    }
+#line 7494 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 298:
+#line 2548 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_if(p, cond((yyvsp[-4].nd)), (yyvsp[-2].nd), (yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-5].num));
+                    }
+#line 7503 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 299:
+#line 2556 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_unless(p, cond((yyvsp[-4].nd)), (yyvsp[-2].nd), (yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-5].num));
+                    }
+#line 7512 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 300:
+#line 2560 "mrbgems/mruby-compiler/core/parse.y"
+                                {COND_PUSH(1);}
+#line 7518 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 301:
+#line 2560 "mrbgems/mruby-compiler/core/parse.y"
+                                                              {COND_POP();}
+#line 7524 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 302:
+#line 2563 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_while(p, cond((yyvsp[-4].nd)), (yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-6].num));
+                    }
+#line 7533 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 303:
+#line 2567 "mrbgems/mruby-compiler/core/parse.y"
+                                {COND_PUSH(1);}
+#line 7539 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 304:
+#line 2567 "mrbgems/mruby-compiler/core/parse.y"
+                                                              {COND_POP();}
+#line 7545 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 305:
+#line 2570 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_until(p, cond((yyvsp[-4].nd)), (yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-6].num));
+                    }
+#line 7554 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 306:
+#line 2577 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_case(p, (yyvsp[-3].nd), (yyvsp[-1].nd));
+                    }
+#line 7562 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 307:
+#line 2581 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_case(p, 0, (yyvsp[-1].nd));
+                    }
+#line 7570 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 308:
+#line 2585 "mrbgems/mruby-compiler/core/parse.y"
+                  {COND_PUSH(1);}
+#line 7576 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 309:
+#line 2587 "mrbgems/mruby-compiler/core/parse.y"
+                  {COND_POP();}
+#line 7582 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 310:
+#line 2590 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_for(p, (yyvsp[-7].nd), (yyvsp[-4].nd), (yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-8].num));
+                    }
+#line 7591 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 311:
+#line 2596 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "class definition in method body");
+                      (yyval.nd) = local_switch(p);
+                      nvars_block(p);
+                    }
+#line 7602 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 312:
+#line 2604 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_class(p, (yyvsp[-4].nd), (yyvsp[-3].nd), (yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-5].num));
+                      local_resume(p, (yyvsp[-2].nd));
+                      nvars_unnest(p);
+                    }
+#line 7613 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 313:
+#line 2612 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.num) = p->in_def;
+                      p->in_def = 0;
+                    }
+#line 7622 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 314:
+#line 2617 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons(local_switch(p), nint(p->in_single));
+                      nvars_block(p);
+                      p->in_single = 0;
+                    }
+#line 7632 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 315:
+#line 2624 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_sclass(p, (yyvsp[-5].nd), (yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-7].num));
+                      local_resume(p, (yyvsp[-2].nd)->car);
+                      nvars_unnest(p);
+                      p->in_def = (yyvsp[-4].num);
+                      p->in_single = intn((yyvsp[-2].nd)->cdr);
+                    }
+#line 7645 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 316:
+#line 2634 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "module definition in method body");
+                      (yyval.nd) = local_switch(p);
+                      nvars_block(p);
+                    }
+#line 7656 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 317:
+#line 2642 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_module(p, (yyvsp[-3].nd), (yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-4].num));
+                      local_resume(p, (yyvsp[-2].nd));
+                      nvars_unnest(p);
+                    }
+#line 7667 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 318:
+#line 2649 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.stack) = p->cmdarg_stack;
+                      p->cmdarg_stack = 0;
+                    }
+#line 7676 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 319:
+#line 2653 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->in_def++;
+                      (yyval.nd) = local_switch(p);
+                      nvars_block(p);
+                    }
+#line 7686 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 320:
+#line 2661 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_def(p, (yyvsp[-5].id), (yyvsp[-2].nd), (yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-6].num));
+                      local_resume(p, (yyvsp[-3].nd));
+                      nvars_unnest(p);
+                      p->in_def--;
+                      p->cmdarg_stack = (yyvsp[-4].stack);
+                    }
+#line 7699 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 321:
+#line 2670 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->lstate = EXPR_FNAME;
+                      (yyval.stack) = p->cmdarg_stack;
+                      p->cmdarg_stack = 0;
+                    }
+#line 7709 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 322:
+#line 2676 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->in_single++;
+                      p->lstate = EXPR_ENDFN; /* force for args */
+                      (yyval.nd) = local_switch(p);
+                      nvars_block(p);
+                    }
+#line 7720 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 323:
+#line 2685 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_sdef(p, (yyvsp[-7].nd), (yyvsp[-4].id), (yyvsp[-2].nd), (yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-8].num));
+                      local_resume(p, (yyvsp[-3].nd));
+                      nvars_unnest(p);
+                      p->in_single--;
+                      p->cmdarg_stack = (yyvsp[-5].stack);
+                    }
+#line 7733 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 324:
+#line 2694 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_break(p, 0);
+                    }
+#line 7741 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 325:
+#line 2698 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_next(p, 0);
+                    }
+#line 7749 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 326:
+#line 2702 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_redo(p);
+                    }
+#line 7757 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 327:
+#line 2706 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_retry(p);
+                    }
+#line 7765 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 328:
+#line 2712 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                      if (!(yyval.nd)) (yyval.nd) = new_nil(p);
+                    }
+#line 7774 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 335:
+#line 2731 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_if(p, cond((yyvsp[-3].nd)), (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 7782 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 337:
+#line 2738 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 7790 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 338:
+#line 2744 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1(list1((yyvsp[0].nd)));
+                    }
+#line 7798 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 340:
+#line 2751 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3((yyvsp[0].nd),0,0);
+                    }
+#line 7806 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 341:
+#line 2755 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3((yyvsp[-3].nd), new_arg(p, (yyvsp[0].id)), 0);
+                    }
+#line 7814 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 342:
+#line 2759 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3((yyvsp[-5].nd), new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd));
+                    }
+#line 7822 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 343:
+#line 2763 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_f(p, 0);
+                      (yyval.nd) = list3((yyvsp[-2].nd), (node*)-1, 0);
+                    }
+#line 7831 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 344:
+#line 2768 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3((yyvsp[-4].nd), (node*)-1, (yyvsp[0].nd));
+                    }
+#line 7839 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 345:
+#line 2772 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3(0, new_arg(p, (yyvsp[0].id)), 0);
+                    }
+#line 7847 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 346:
+#line 2776 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3(0, new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd));
+                    }
+#line 7855 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 347:
+#line 2780 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_f(p, 0);
+                      (yyval.nd) = list3(0, (node*)-1, 0);
+                    }
+#line 7864 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 348:
+#line 2785 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_f(p, 0);
+                    }
+#line 7872 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 349:
+#line 2789 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list3(0, (node*)-1, (yyvsp[0].nd));
+                    }
+#line 7880 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 350:
+#line 2795 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id));
+                    }
+#line 7888 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 351:
+#line 2799 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id));
+                    }
+#line 7896 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 352:
+#line 2803 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id));
+                    }
+#line 7904 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 353:
+#line 2807 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id));
+                    }
+#line 7912 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 354:
+#line 2813 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 7920 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 355:
+#line 2817 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args_tail(p, 0, 0, 0);
+                    }
+#line 7928 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 356:
+#line 2823 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd));
+                    }
+#line 7936 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 357:
+#line 2827 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-7].nd), (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 7944 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 358:
+#line 2831 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd));
+                    }
+#line 7952 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 359:
+#line 2835 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 7960 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 360:
+#line 2839 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd));
+                    }
+#line 7968 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 361:
+#line 2843 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-2].nd), 0, 0, 0, (yyvsp[0].nd));
+                    }
+#line 7976 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 362:
+#line 2847 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-5].nd), 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 7984 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 363:
+#line 2851 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd));
+                    }
+#line 7992 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 364:
+#line 2855 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd));
+                    }
+#line 8000 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 365:
+#line 2859 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 8008 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 366:
+#line 2863 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd));
+                    }
+#line 8016 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 367:
+#line 2867 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 8024 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 368:
+#line 2871 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd));
+                    }
+#line 8032 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 369:
+#line 2875 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 8040 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 370:
+#line 2879 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd));
+                    }
+#line 8048 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 371:
+#line 2885 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_blk(p, 0);
+                      (yyval.nd) = 0;
+                    }
+#line 8057 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 372:
+#line 2890 "mrbgems/mruby-compiler/core/parse.y"
+                   {
+                      p->cmd_start = TRUE;
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 8066 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 373:
+#line 2896 "mrbgems/mruby-compiler/core/parse.y"
+                      {local_add_blk(p, 0);}
+#line 8072 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 374:
+#line 2897 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = 0;
+                    }
+#line 8080 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 375:
+#line 2901 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_blk(p, 0);
+                      (yyval.nd) = 0;
+                    }
+#line 8089 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 376:
+#line 2906 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-2].nd);
+                    }
+#line 8097 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 377:
+#line 2913 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = 0;
+                    }
+#line 8105 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 378:
+#line 2917 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = 0;
+                    }
+#line 8113 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 381:
+#line 2927 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_f(p, (yyvsp[0].id));
+                      new_bv(p, (yyvsp[0].id));
+                    }
+#line 8122 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 383:
+#line 2935 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-2].nd);
+                    }
+#line 8130 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 384:
+#line 2939 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 8138 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 385:
+#line 2945 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 8146 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 386:
+#line 2949 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 8154 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 387:
+#line 2955 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_nest(p);
+                      nvars_nest(p);
+                    }
+#line 8163 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 388:
+#line 2962 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_block(p,(yyvsp[-2].nd),(yyvsp[-1].nd));
+                      local_unnest(p);
+                      nvars_unnest(p);
+                    }
+#line 8173 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 389:
+#line 2970 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if ((yyvsp[-1].nd)->car == (node*)NODE_YIELD) {
+                        yyerror(p, "block given to yield");
+                      }
+                      else {
+                        call_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd));
+                      }
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 8187 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 390:
+#line 2980 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num));
+                    }
+#line 8195 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 391:
+#line 2984 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), (yyvsp[-3].num));
+                      call_with_block(p, (yyval.nd), (yyvsp[0].nd));
+                    }
+#line 8204 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 392:
+#line 2989 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), (yyvsp[-3].num));
+                      call_with_block(p, (yyval.nd), (yyvsp[0].nd));
+                    }
+#line 8213 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 393:
+#line 2996 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd));
+                    }
+#line 8221 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 394:
+#line 3000 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num));
+                    }
+#line 8229 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 395:
+#line 3004 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2);
+                    }
+#line 8237 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 396:
+#line 3008 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2);
+                    }
+#line 8245 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 397:
+#line 3012 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-2].nd), intern_lit("call"), (yyvsp[0].nd), (yyvsp[-1].num));
+                    }
+#line 8253 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 398:
+#line 3016 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-2].nd), intern_lit("call"), (yyvsp[0].nd), tCOLON2);
+                    }
+#line 8261 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 399:
+#line 3020 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_super(p, (yyvsp[0].nd));
+                    }
+#line 8269 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 400:
+#line 3024 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_zsuper(p);
+                    }
+#line 8277 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 401:
+#line 3028 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_lit("[]"), (yyvsp[-1].nd), '.');
+                    }
+#line 8285 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 402:
+#line 3034 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_nest(p);
+                      nvars_nest(p);
+                      (yyval.num) = p->lineno;
+                    }
+#line 8295 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 403:
+#line 3041 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_block(p,(yyvsp[-2].nd),(yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-3].num));
+                      local_unnest(p);
+                      nvars_unnest(p);
+                    }
+#line 8306 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 404:
+#line 3048 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_nest(p);
+                      nvars_nest(p);
+                      (yyval.num) = p->lineno;
+                    }
+#line 8316 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 405:
+#line 3055 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_block(p,(yyvsp[-2].nd),(yyvsp[-1].nd));
+                      SET_LINENO((yyval.nd), (yyvsp[-3].num));
+                      local_unnest(p);
+                      nvars_unnest(p);
+                    }
+#line 8327 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 406:
+#line 3066 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = cons(cons((yyvsp[-3].nd), (yyvsp[-1].nd)), (yyvsp[0].nd));
+                    }
+#line 8335 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 407:
+#line 3072 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if ((yyvsp[0].nd)) {
+                        (yyval.nd) = cons(cons(0, (yyvsp[0].nd)), 0);
+                      }
+                      else {
+                        (yyval.nd) = 0;
+                      }
+                    }
+#line 8348 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 409:
+#line 3086 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1(list3((yyvsp[-4].nd), (yyvsp[-3].nd), (yyvsp[-1].nd)));
+                      if ((yyvsp[0].nd)) (yyval.nd) = append((yyval.nd), (yyvsp[0].nd));
+                    }
+#line 8357 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 411:
+#line 3094 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                        (yyval.nd) = list1((yyvsp[0].nd));
+                    }
+#line 8365 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 414:
+#line 3102 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 8373 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 416:
+#line 3109 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 8381 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 423:
+#line 3123 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = concat_string(p, (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 8389 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 426:
+#line 3131 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 8397 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 427:
+#line 3135 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_dstr(p, push((yyvsp[-1].nd), (yyvsp[0].nd)));
+                    }
+#line 8405 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 429:
+#line 3142 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = append((yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 8413 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 430:
+#line 3148 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1((yyvsp[0].nd));
+                    }
+#line 8421 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 431:
+#line 3152 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = p->lex_strterm;
+                      p->lex_strterm = NULL;
+                    }
+#line 8430 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 432:
+#line 3158 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->lex_strterm = (yyvsp[-2].nd);
+                      (yyval.nd) = list2((yyvsp[-3].nd), (yyvsp[-1].nd));
+                    }
+#line 8439 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 433:
+#line 3163 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1(new_literal_delim(p));
+                    }
+#line 8447 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 434:
+#line 3167 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1(new_literal_delim(p));
+                    }
+#line 8455 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 435:
+#line 3173 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                        (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 8463 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 436:
+#line 3177 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_dxstr(p, push((yyvsp[-1].nd), (yyvsp[0].nd)));
+                    }
+#line 8471 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 437:
+#line 3183 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                        (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 8479 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 438:
+#line 3187 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_dregx(p, (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 8487 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 442:
+#line 3200 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      parser_heredoc_info * inf = parsing_heredoc_inf(p);
+                      inf->doc = push(inf->doc, new_str(p, "", 0));
+                      heredoc_end(p);
+                    }
+#line 8497 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 443:
+#line 3206 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      heredoc_end(p);
+                    }
+#line 8505 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 446:
+#line 3216 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      parser_heredoc_info * inf = parsing_heredoc_inf(p);
+                      inf->doc = push(inf->doc, (yyvsp[0].nd));
+                      heredoc_treat_nextline(p);
+                    }
+#line 8515 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 447:
+#line 3222 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = p->lex_strterm;
+                      p->lex_strterm = NULL;
+                    }
+#line 8524 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 448:
+#line 3228 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      parser_heredoc_info * inf = parsing_heredoc_inf(p);
+                      p->lex_strterm = (yyvsp[-2].nd);
+                      inf->doc = push(push(inf->doc, (yyvsp[-3].nd)), (yyvsp[-1].nd));
+                    }
+#line 8534 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 449:
+#line 3236 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_words(p, list1((yyvsp[0].nd)));
+                    }
+#line 8542 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 450:
+#line 3240 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_words(p, push((yyvsp[-1].nd), (yyvsp[0].nd)));
+                    }
+#line 8550 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 451:
+#line 3247 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->lstate = EXPR_ENDARG;
+                      (yyval.nd) = new_sym(p, (yyvsp[0].id));
+                    }
+#line 8559 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 452:
+#line 3252 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->lstate = EXPR_ENDARG;
+                      (yyval.nd) = new_dsym(p, new_dstr(p, push((yyvsp[-1].nd), (yyvsp[0].nd))));
+                    }
+#line 8568 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 453:
+#line 3259 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.id) = (yyvsp[0].id);
+                    }
+#line 8576 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 458:
+#line 3269 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.id) = new_strsym(p, (yyvsp[0].nd));
+                    }
+#line 8584 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 459:
+#line 3273 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.id) = new_strsym(p, (yyvsp[0].nd));
+                    }
+#line 8592 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 460:
+#line 3279 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_symbols(p, list1((yyvsp[0].nd)));
+                    }
+#line 8600 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 461:
+#line 3283 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_symbols(p, push((yyvsp[-1].nd), (yyvsp[0].nd)));
+                    }
+#line 8608 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 464:
+#line 3291 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = negate_lit(p, (yyvsp[0].nd));
+                    }
+#line 8616 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 465:
+#line 3295 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = negate_lit(p, (yyvsp[0].nd));
+                    }
+#line 8624 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 466:
+#line 3301 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_lvar(p, (yyvsp[0].id));
+                    }
+#line 8632 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 467:
+#line 3305 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_ivar(p, (yyvsp[0].id));
+                    }
+#line 8640 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 468:
+#line 3309 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_gvar(p, (yyvsp[0].id));
+                    }
+#line 8648 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 469:
+#line 3313 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_cvar(p, (yyvsp[0].id));
+                    }
+#line 8656 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 470:
+#line 3317 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_const(p, (yyvsp[0].id));
+                    }
+#line 8664 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 471:
+#line 3323 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      assignable(p, (yyvsp[0].nd));
+                    }
+#line 8672 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 472:
+#line 3327 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "can't assign to numbered parameter");
+                    }
+#line 8680 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 473:
+#line 3333 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = var_reference(p, (yyvsp[0].nd));
+                    }
+#line 8688 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 474:
+#line 3337 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_nil(p);
+                    }
+#line 8696 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 475:
+#line 3341 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_self(p);
+                    }
+#line 8704 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 476:
+#line 3345 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_true(p);
+                    }
+#line 8712 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 477:
+#line 3349 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_false(p);
+                    }
+#line 8720 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 478:
+#line 3353 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
+                      if (!fn) {
+                        fn = "(null)";
+                      }
+                      (yyval.nd) = new_str(p, fn, strlen(fn));
+                    }
+#line 8732 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 479:
+#line 3361 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      char buf[16];
+
+                      dump_int(p->lineno, buf);
+                      (yyval.nd) = new_int(p, buf, 10, 0);
+                    }
+#line 8743 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 480:
+#line 3368 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+#ifdef MRB_UTF8_STRING
+                      const char *enc = "UTF-8";
+#else
+                      const char *enc = "ASCII-8BIT";
+#endif
+                      (yyval.nd) = new_str(p, enc, strlen(enc));
+                    }
+#line 8756 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 483:
+#line 3383 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = 0;
+                    }
+#line 8764 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 484:
+#line 3387 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->lstate = EXPR_BEG;
+                      p->cmd_start = TRUE;
+                    }
+#line 8773 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 485:
+#line 3392 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 8781 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 486:
+#line 3403 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                      p->lstate = EXPR_BEG;
+                      p->cmd_start = TRUE;
+                    }
+#line 8791 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 487:
+#line 3409 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+#if 1
+                      /* til real keyword args implemented */
+                      mrb_sym r = mrb_intern_lit(p->mrb, "*");
+                      mrb_sym b = mrb_intern_lit(p->mrb, "&");
+                      local_add_f(p, r);
+                      (yyval.nd) = new_args(p, 0, 0, r, 0,
+                                    new_args_tail(p, 0, 0, b));
+#else
+                      mrb_sym r = mrb_intern_lit(p->mrb, "*");
+                      mrb_sym k = mrb_intern_lit(p->mrb, "**");
+                      mrb_sym b = mrb_intern_lit(p->mrb, "&");
+                      local_add_f(p, r); local_add_f(p, k);
+                      (yyval.nd) = new_args(p, 0, 0, r, 0,
+                                    new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b));
+#endif
+                    }
+#line 8813 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 488:
+#line 3427 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 8821 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 489:
+#line 3433 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_nest(p);
+                    }
+#line 8829 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 490:
+#line 3439 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = new_kw_arg(p, (yyvsp[-1].id), cons((yyvsp[0].nd), locals_node(p)));
+                      local_unnest(p);
+                    }
+#line 8839 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 491:
+#line 3445 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0);
+                      local_unnest(p);
+                    }
+#line 8848 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 492:
+#line 3452 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_kw_arg(p, (yyvsp[-1].id), cons((yyvsp[0].nd), locals_node(p)));
+                      local_unnest(p);
+                    }
+#line 8857 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 493:
+#line 3457 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0);
+                      local_unnest(p);
+                    }
+#line 8866 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 494:
+#line 3464 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1((yyvsp[0].nd));
+                    }
+#line 8874 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 495:
+#line 3468 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 8882 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 496:
+#line 3474 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1((yyvsp[0].nd));
+                    }
+#line 8890 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 497:
+#line 3478 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 8898 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 500:
+#line 3488 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_kw_rest_args(p, nsym((yyvsp[0].id)));
+                    }
+#line 8906 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 501:
+#line 3492 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_kw_rest_args(p, 0);
+                    }
+#line 8914 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 502:
+#line 3498 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id));
+                    }
+#line 8922 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 503:
+#line 3502 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id));
+                    }
+#line 8930 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 504:
+#line 3506 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id));
+                    }
+#line 8938 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 505:
+#line 3510 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id));
+                    }
+#line 8946 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 506:
+#line 3516 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                    }
+#line 8954 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 507:
+#line 3520 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args_tail(p, 0, 0, 0);
+                    }
+#line 8962 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 508:
+#line 3526 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd));
+                    }
+#line 8970 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 509:
+#line 3530 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-7].nd), (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 8978 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 510:
+#line 3534 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd));
+                    }
+#line 8986 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 511:
+#line 3538 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 8994 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 512:
+#line 3542 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd));
+                    }
+#line 9002 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 513:
+#line 3546 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-5].nd), 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 9010 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 514:
+#line 3550 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd));
+                    }
+#line 9018 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 515:
+#line 3554 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd));
+                    }
+#line 9026 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 516:
+#line 3558 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 9034 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 517:
+#line 3562 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd));
+                    }
+#line 9042 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 518:
+#line 3566 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 9050 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 519:
+#line 3570 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd));
+                    }
+#line 9058 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 520:
+#line 3574 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd));
+                    }
+#line 9066 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 521:
+#line 3578 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd));
+                    }
+#line 9074 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 522:
+#line 3582 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_f(p, mrb_intern_lit(p->mrb, "&"));
+                      (yyval.nd) = new_args(p, 0, 0, 0, 0, 0);
+                    }
+#line 9083 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 523:
+#line 3589 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "formal argument cannot be a constant");
+                      (yyval.nd) = 0;
+                    }
+#line 9092 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 524:
+#line 3594 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "formal argument cannot be an instance variable");
+                      (yyval.nd) = 0;
+                    }
+#line 9101 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 525:
+#line 3599 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "formal argument cannot be a global variable");
+                      (yyval.nd) = 0;
+                    }
+#line 9110 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 526:
+#line 3604 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "formal argument cannot be a class variable");
+                      (yyval.nd) = 0;
+                    }
+#line 9119 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 527:
+#line 3609 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      yyerror(p, "formal argument cannot be a numbered parameter");
+                      (yyval.nd) = 0;
+                    }
+#line 9128 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 528:
+#line 3616 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.id) = 0;
+                    }
+#line 9136 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 529:
+#line 3620 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_f(p, (yyvsp[0].id));
+                      (yyval.id) = (yyvsp[0].id);
+                    }
+#line 9145 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 530:
+#line 3627 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_arg(p, (yyvsp[0].id));
+                    }
+#line 9153 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 531:
+#line 3631 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = local_switch(p);
+                    }
+#line 9161 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 532:
+#line 3635 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = new_masgn_param(p, (yyvsp[-1].nd), p->locals->car);
+                      local_resume(p, (yyvsp[-2].nd));
+                      local_add_f(p, 0);
+                    }
+#line 9171 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 533:
+#line 3643 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1((yyvsp[0].nd));
+                    }
+#line 9179 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 534:
+#line 3647 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 9187 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 535:
+#line 3653 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_f(p, (yyvsp[-1].id));
+                      local_nest(p);
+                      (yyval.id) = (yyvsp[-1].id);
+                    }
+#line 9197 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 536:
+#line 3661 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = cons(nsym((yyvsp[-1].id)), cons((yyvsp[0].nd), locals_node(p)));
+                      local_unnest(p);
+                    }
+#line 9207 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 537:
+#line 3669 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = cons(nsym((yyvsp[-1].id)), cons((yyvsp[0].nd), locals_node(p)));
+                      local_unnest(p);
+                    }
+#line 9217 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 538:
+#line 3677 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1((yyvsp[0].nd));
+                    }
+#line 9225 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 539:
+#line 3681 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 9233 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 540:
+#line 3687 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1((yyvsp[0].nd));
+                    }
+#line 9241 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 541:
+#line 3691 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 9249 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 544:
+#line 3701 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_f(p, (yyvsp[0].id));
+                      (yyval.id) = (yyvsp[0].id);
+                    }
+#line 9258 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 545:
+#line 3706 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      local_add_f(p, mrb_intern_lit(p->mrb, "*"));
+                      (yyval.id) = -1;
+                    }
+#line 9267 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 548:
+#line 3717 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.id) = (yyvsp[0].id);
+                    }
+#line 9275 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 549:
+#line 3723 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.id) = (yyvsp[0].id);
+                    }
+#line 9283 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 550:
+#line 3727 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.id) = 0;
+                    }
+#line 9291 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 551:
+#line 3733 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[0].nd);
+                      if (!(yyval.nd)) (yyval.nd) = new_nil(p);
+                    }
+#line 9300 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 552:
+#line 3737 "mrbgems/mruby-compiler/core/parse.y"
+                      {p->lstate = EXPR_BEG;}
+#line 9306 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 553:
+#line 3738 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      if ((yyvsp[-1].nd) == 0) {
+                        yyerror(p, "can't define singleton method for ().");
+                      }
+                      else {
+                        switch ((enum node_type)intn((yyvsp[-1].nd)->car)) {
+                        case NODE_STR:
+                        case NODE_DSTR:
+                        case NODE_XSTR:
+                        case NODE_DXSTR:
+                        case NODE_DREGX:
+                        case NODE_MATCH:
+                        case NODE_FLOAT:
+                        case NODE_ARRAY:
+                        case NODE_HEREDOC:
+                          yyerror(p, "can't define singleton method for literals");
+                        default:
+                          break;
+                        }
+                      }
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 9333 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 555:
+#line 3764 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = (yyvsp[-1].nd);
+                    }
+#line 9341 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 556:
+#line 3770 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = list1((yyvsp[0].nd));
+                      NODE_LINENO((yyval.nd), (yyvsp[0].nd));
+                    }
+#line 9350 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 557:
+#line 3775 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 9358 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 560:
+#line 3785 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[-2].nd));
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = cons((yyvsp[-2].nd), (yyvsp[0].nd));
+                    }
+#line 9368 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 561:
+#line 3791 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = cons(new_sym(p, (yyvsp[-2].id)), (yyvsp[0].nd));
+                    }
+#line 9377 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 562:
+#line 3796 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      if ((yyvsp[-2].nd)->car == (node*)NODE_DSTR) {
+                        (yyval.nd) = cons(new_dsym(p, (yyvsp[-2].nd)), (yyvsp[0].nd));
+                      }
+                      else {
+                        (yyval.nd) = cons(new_sym(p, new_strsym(p, (yyvsp[-2].nd))), (yyvsp[0].nd));
+                      }
+                    }
+#line 9391 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 563:
+#line 3806 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      void_expr_error(p, (yyvsp[0].nd));
+                      (yyval.nd) = cons(new_kw_rest_args(p, 0), (yyvsp[0].nd));
+                    }
+#line 9400 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 576:
+#line 3833 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.num) = '.';
+                    }
+#line 9408 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 577:
+#line 3837 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.num) = 0;
+                    }
+#line 9416 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 579:
+#line 3844 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.num) = tCOLON2;
+                    }
+#line 9424 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 588:
+#line 3865 "mrbgems/mruby-compiler/core/parse.y"
+                      {yyerrok;}
+#line 9430 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 591:
+#line 3871 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      p->lineno += (yyvsp[0].num);
+                      p->column = 0;
+                    }
+#line 9439 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+  case 594:
+#line 3882 "mrbgems/mruby-compiler/core/parse.y"
+                    {
+                      (yyval.nd) = 0;
+                    }
+#line 9447 "mrbgems/mruby-compiler/core/y.tab.c"
+    break;
+
+
+#line 9451 "mrbgems/mruby-compiler/core/y.tab.c"
+
+      default: break;
+    }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+  /* Now 'shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+  {
+    const int yylhs = yyr1[yyn] - YYNTOKENS;
+    const int yyi = yypgoto[yylhs] + *yyssp;
+    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+               ? yytable[yyi]
+               : yydefgoto[yylhs]);
+  }
+
+  goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error.  |
+`--------------------------------------*/
+yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (p, YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
+      {
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc)));
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (p, yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
+      }
+# undef YYSYNTAX_ERROR
+#endif
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+         error, discard it.  */
+
+      if (yychar <= YYEOF)
+        {
+          /* Return failure if at end of input.  */
+          if (yychar == YYEOF)
+            YYABORT;
+        }
+      else
+        {
+          yydestruct ("Error: discarding",
+                      yytoken, &yylval, p);
+          yychar = YYEMPTY;
+        }
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+  /* Pacify compilers when the user code never invokes YYERROR and the
+     label yyerrorlab therefore never appears in user code.  */
+  if (0)
+    YYERROR;
+
+  /* Do not reclaim the symbols of the rule whose action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (!yypact_value_is_default (yyn))
+        {
+          yyn += YYTERROR;
+          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+            {
+              yyn = yytable[yyn];
+              if (0 < yyn)
+                break;
+            }
+        }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+        YYABORT;
+
+
+      yydestruct ("Error: popping",
+                  yystos[yystate], yyvsp, p);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (p, YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result.  |
+`-----------------------------------------------------*/
+yyreturn:
+  if (yychar != YYEMPTY)
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval, p);
+    }
+  /* Do not reclaim the symbols of the rule whose action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                  yystos[+*yyssp], yyvsp, p);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  return yyresult;
+}
+#line 3886 "mrbgems/mruby-compiler/core/parse.y"
+
+#define pylval  (*((YYSTYPE*)(p->ylval)))
+
+static void
+yyerror(parser_state *p, const char *s)
+{
+  char* c;
+  size_t n;
+
+  if (! p->capture_errors) {
+#ifndef MRB_DISABLE_STDIO
+    if (p->filename_sym) {
+      const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
+      fprintf(stderr, "%s:%d:%d: %s\n", filename, p->lineno, p->column, s);
+    }
+    else {
+      fprintf(stderr, "line %d:%d: %s\n", p->lineno, p->column, s);
+    }
+#endif
+  }
+  else if (p->nerr < sizeof(p->error_buffer) / sizeof(p->error_buffer[0])) {
+    n = strlen(s);
+    c = (char *)parser_palloc(p, n + 1);
+    memcpy(c, s, n + 1);
+    p->error_buffer[p->nerr].message = c;
+    p->error_buffer[p->nerr].lineno = p->lineno;
+    p->error_buffer[p->nerr].column = p->column;
+  }
+  p->nerr++;
+}
+
+static void
+yyerror_c(parser_state *p, const char *msg, char c)
+{
+  char buf[256];
+
+  strncpy(buf, msg, sizeof(buf) - 2);
+  buf[sizeof(buf) - 2] = '\0';
+  strncat(buf, &c, 1);
+  yyerror(p, buf);
+}
+
+static void
+yywarn(parser_state *p, const char *s)
+{
+  char* c;
+  size_t n;
+
+  if (! p->capture_errors) {
+#ifndef MRB_DISABLE_STDIO
+    if (p->filename_sym) {
+      const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
+      fprintf(stderr, "%s:%d:%d: warning: %s\n", filename, p->lineno, p->column, s);
+    }
+    else {
+      fprintf(stderr, "line %d:%d: warning: %s\n", p->lineno, p->column, s);
+    }
+#endif
+  }
+  else if (p->nwarn < sizeof(p->warn_buffer) / sizeof(p->warn_buffer[0])) {
+    n = strlen(s);
+    c = (char *)parser_palloc(p, n + 1);
+    memcpy(c, s, n + 1);
+    p->warn_buffer[p->nwarn].message = c;
+    p->warn_buffer[p->nwarn].lineno = p->lineno;
+    p->warn_buffer[p->nwarn].column = p->column;
+  }
+  p->nwarn++;
+}
+
+static void
+yywarning(parser_state *p, const char *s)
+{
+  yywarn(p, s);
+}
+
+static void
+yywarning_s(parser_state *p, const char *msg, const char *s)
+{
+  char buf[256];
+
+  strncpy(buf, msg, sizeof(buf) - 1);
+  buf[sizeof(buf) - 1] = '\0';
+  strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1);
+  strncat(buf, s, sizeof(buf) - strlen(buf) - 1);
+  yywarning(p, buf);
+}
+
+static void
+backref_error(parser_state *p, node *n)
+{
+  int c;
+
+  c = intn(n->car);
+
+  if (c == NODE_NTH_REF) {
+    yyerror_c(p, "can't set variable $", (char)intn(n->cdr)+'0');
+  }
+  else if (c == NODE_BACK_REF) {
+    yyerror_c(p, "can't set variable $", (char)intn(n->cdr));
+  }
+  else {
+    mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %d", c);
+  }
+}
+
+static void
+void_expr_error(parser_state *p, node *n)
+{
+  int c;
+
+  if (n == NULL) return;
+  c = intn(n->car);
+  switch (c) {
+  case NODE_BREAK:
+  case NODE_RETURN:
+  case NODE_NEXT:
+  case NODE_REDO:
+  case NODE_RETRY:
+    yyerror(p, "void value expression");
+    break;
+  case NODE_AND:
+  case NODE_OR:
+    if (n->cdr) {
+      void_expr_error(p, n->cdr->car);
+      void_expr_error(p, n->cdr->cdr);
+    }
+    break;
+  case NODE_BEGIN:
+    if (n->cdr) {
+      while (n->cdr) {
+        n = n->cdr;
+      }
+      void_expr_error(p, n->car);
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+static void pushback(parser_state *p, int c);
+static mrb_bool peeks(parser_state *p, const char *s);
+static mrb_bool skips(parser_state *p, const char *s);
+
+static inline int
+nextc0(parser_state *p)
+{
+  int c;
+#ifndef MRB_DISABLE_STDIO
+  if (p->f) {
+    if (feof(p->f)) return -1;
+    c = fgetc(p->f);
+    if (c == EOF) return -1;
+  }
+  else
+#endif
+    if (!p->s || p->s >= p->send) {
+      return -1;
+    }
+    else {
+      c = (unsigned char)*p->s++;
+    }
+  return c;
+}
+
+static inline int
+nextc(parser_state *p)
+{
+  int c;
+
+  if (p->pb) {
+    node *tmp;
+
+    c = intn(p->pb->car);
+    tmp = p->pb;
+    p->pb = p->pb->cdr;
+    cons_free(tmp);
+  }
+  else {
+    c = nextc0(p);
+    if (c < 0) goto eof;
+  }
+  if (c >= 0) {
+    p->column++;
+  }
+  if (c == '\r') {
+    const int lf = nextc0(p);
+    if (lf == '\n') {
+      return '\n';
+    }
+    if (lf > 0) pushback(p, lf);
+  }
+  return c;
+
+  eof:
+  if (!p->cxt) return -1;
+  else {
+    if (p->cxt->partial_hook(p) < 0)
+      return -1;                /* end of program(s) */
+    return -2;                  /* end of a file in the program files */
+  }
+}
+
+static void
+pushback(parser_state *p, int c)
+{
+  if (c >= 0) {
+    p->column--;
+  }
+  p->pb = cons(nint(c), p->pb);
+}
+
+static void
+skip(parser_state *p, char term)
+{
+  int c;
+
+  for (;;) {
+    c = nextc(p);
+    if (c < 0) break;
+    if (c == term) break;
+  }
+}
+
+static int
+peekc_n(parser_state *p, int n)
+{
+  node *list = 0;
+  int c0;
+
+  do {
+    c0 = nextc(p);
+    if (c0 == -1) return c0;    /* do not skip partial EOF */
+    if (c0 >= 0) --p->column;
+    list = push(list, nint(c0));
+  } while(n--);
+  if (p->pb) {
+    p->pb = append((node*)list, p->pb);
+  }
+  else {
+    p->pb = list;
+  }
+  return c0;
+}
+
+static mrb_bool
+peek_n(parser_state *p, int c, int n)
+{
+  return peekc_n(p, n) == c && c >= 0;
+}
+#define peek(p,c) peek_n((p), (c), 0)
+
+static mrb_bool
+peeks(parser_state *p, const char *s)
+{
+  size_t len = strlen(s);
+
+#ifndef MRB_DISABLE_STDIO
+  if (p->f) {
+    int n = 0;
+    while (*s) {
+      if (!peek_n(p, *s++, n++)) return FALSE;
+    }
+    return TRUE;
+  }
+  else
+#endif
+    if (p->s && p->s + len <= p->send) {
+      if (memcmp(p->s, s, len) == 0) return TRUE;
+    }
+  return FALSE;
+}
+
+static mrb_bool
+skips(parser_state *p, const char *s)
+{
+  int c;
+
+  for (;;) {
+    /* skip until first char */
+    for (;;) {
+      c = nextc(p);
+      if (c < 0) return FALSE;
+      if (c == '\n') {
+        p->lineno++;
+        p->column = 0;
+      }
+      if (c == *s) break;
+    }
+    s++;
+    if (peeks(p, s)) {
+      size_t len = strlen(s);
+
+      while (len--) {
+        if (nextc(p) == '\n') {
+          p->lineno++;
+          p->column = 0;
+        }
+      }
+      return TRUE;
+    }
+    else{
+      s--;
+    }
+  }
+  return FALSE;
+}
+
+
+static int
+newtok(parser_state *p)
+{
+  if (p->tokbuf != p->buf) {
+    mrb_free(p->mrb, p->tokbuf);
+    p->tokbuf = p->buf;
+    p->tsiz = MRB_PARSER_TOKBUF_SIZE;
+  }
+  p->tidx = 0;
+  return p->column - 1;
+}
+
+static void
+tokadd(parser_state *p, int32_t c)
+{
+  char utf8[4];
+  int i, len;
+
+  /* mrb_assert(-0x10FFFF <= c && c <= 0xFF); */
+  if (c >= 0) {
+    /* Single byte from source or non-Unicode escape */
+    utf8[0] = (char)c;
+    len = 1;
+  }
+  else {
+    /* Unicode character */
+    c = -c;
+    if (c < 0x80) {
+      utf8[0] = (char)c;
+      len = 1;
+    }
+    else if (c < 0x800) {
+      utf8[0] = (char)(0xC0 | (c >> 6));
+      utf8[1] = (char)(0x80 | (c & 0x3F));
+      len = 2;
+    }
+    else if (c < 0x10000) {
+      utf8[0] = (char)(0xE0 |  (c >> 12)        );
+      utf8[1] = (char)(0x80 | ((c >>  6) & 0x3F));
+      utf8[2] = (char)(0x80 | ( c        & 0x3F));
+      len = 3;
+    }
+    else {
+      utf8[0] = (char)(0xF0 |  (c >> 18)        );
+      utf8[1] = (char)(0x80 | ((c >> 12) & 0x3F));
+      utf8[2] = (char)(0x80 | ((c >>  6) & 0x3F));
+      utf8[3] = (char)(0x80 | ( c        & 0x3F));
+      len = 4;
+    }
+  }
+  if (p->tidx+len >= p->tsiz) {
+    if (p->tsiz >= MRB_PARSER_TOKBUF_MAX) {
+      p->tidx += len;
+      return;
+    }
+    p->tsiz *= 2;
+    if (p->tokbuf == p->buf) {
+      p->tokbuf = (char*)mrb_malloc(p->mrb, p->tsiz);
+      memcpy(p->tokbuf, p->buf, MRB_PARSER_TOKBUF_SIZE);
+    }
+    else {
+      p->tokbuf = (char*)mrb_realloc(p->mrb, p->tokbuf, p->tsiz);
+    }
+  }
+  for (i = 0; i < len; i++) {
+    p->tokbuf[p->tidx++] = utf8[i];
+  }
+}
+
+static int
+toklast(parser_state *p)
+{
+  return p->tokbuf[p->tidx-1];
+}
+
+static void
+tokfix(parser_state *p)
+{
+  if (p->tidx >= MRB_PARSER_TOKBUF_MAX) {
+    p->tidx = MRB_PARSER_TOKBUF_MAX-1;
+    yyerror(p, "string too long (truncated)");
+  }
+  p->tokbuf[p->tidx] = '\0';
+}
+
+static const char*
+tok(parser_state *p)
+{
+  return p->tokbuf;
+}
+
+static int
+toklen(parser_state *p)
+{
+  return p->tidx;
+}
+
+#define IS_ARG() (p->lstate == EXPR_ARG || p->lstate == EXPR_CMDARG)
+#define IS_END() (p->lstate == EXPR_END || p->lstate == EXPR_ENDARG || p->lstate == EXPR_ENDFN)
+#define IS_BEG() (p->lstate == EXPR_BEG || p->lstate == EXPR_MID || p->lstate == EXPR_VALUE || p->lstate == EXPR_CLASS)
+#define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
+#define IS_LABEL_POSSIBLE() ((p->lstate == EXPR_BEG && !cmd_state) || IS_ARG())
+#define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
+
+static int32_t
+scan_oct(const int *start, int len, int *retlen)
+{
+  const int *s = start;
+  int32_t retval = 0;
+
+  /* mrb_assert(len <= 3) */
+  while (len-- && *s >= '0' && *s <= '7') {
+    retval <<= 3;
+    retval |= *s++ - '0';
+  }
+  *retlen = (int)(s - start);
+
+  return retval;
+}
+
+static int32_t
+scan_hex(parser_state *p, const int *start, int len, int *retlen)
+{
+  static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
+  const int *s = start;
+  uint32_t retval = 0;
+  char *tmp;
+
+  /* mrb_assert(len <= 8) */
+  while (len-- && *s && (tmp = (char*)strchr(hexdigit, *s))) {
+    retval <<= 4;
+    retval |= (tmp - hexdigit) & 15;
+    s++;
+  }
+  *retlen = (int)(s - start);
+
+  return (int32_t)retval;
+}
+
+static int32_t
+read_escape_unicode(parser_state *p, int limit)
+{
+  int buf[9];
+  int i;
+  int32_t hex;
+
+  /* Look for opening brace */
+  i = 0;
+  buf[0] = nextc(p);
+  if (buf[0] < 0) {
+  eof:
+    yyerror(p, "invalid escape character syntax");
+    return -1;
+  }
+  if (ISXDIGIT(buf[0])) {
+    /* \uxxxx form */
+    for (i=1; i<limit; i++) {
+      buf[i] = nextc(p);
+      if (buf[i] < 0) goto eof;
+      if (!ISXDIGIT(buf[i])) {
+        pushback(p, buf[i]);
+        break;
+      }
+    }
+  }
+  else {
+    pushback(p, buf[0]);
+  }
+  hex = scan_hex(p, buf, i, &i);
+  if (i == 0 || hex > 0x10FFFF || (hex & 0xFFFFF800) == 0xD800) {
+    yyerror(p, "invalid Unicode code point");
+    return -1;
+  }
+  return hex;
+}
+
+/* Return negative to indicate Unicode code point */
+static int32_t
+read_escape(parser_state *p)
+{
+  int32_t c;
+
+  switch (c = nextc(p)) {
+  case '\\':/* Backslash */
+    return c;
+
+  case 'n':/* newline */
+    return '\n';
+
+  case 't':/* horizontal tab */
+    return '\t';
+
+  case 'r':/* carriage-return */
+    return '\r';
+
+  case 'f':/* form-feed */
+    return '\f';
+
+  case 'v':/* vertical tab */
+    return '\13';
+
+  case 'a':/* alarm(bell) */
+    return '\007';
+
+  case 'e':/* escape */
+    return 033;
+
+  case '0': case '1': case '2': case '3': /* octal constant */
+  case '4': case '5': case '6': case '7':
+  {
+    int buf[3];
+    int i;
+
+    buf[0] = c;
+    for (i=1; i<3; i++) {
+      buf[i] = nextc(p);
+      if (buf[i] < 0) goto eof;
+      if (buf[i] < '0' || '7' < buf[i]) {
+        pushback(p, buf[i]);
+        break;
+      }
+    }
+    c = scan_oct(buf, i, &i);
+  }
+  return c;
+
+  case 'x':     /* hex constant */
+  {
+    int buf[2];
+    int i;
+
+    for (i=0; i<2; i++) {
+      buf[i] = nextc(p);
+      if (buf[i] < 0) goto eof;
+      if (!ISXDIGIT(buf[i])) {
+        pushback(p, buf[i]);
+        break;
+      }
+    }
+    if (i == 0) {
+      yyerror(p, "invalid hex escape");
+      return -1;
+    }
+    return scan_hex(p, buf, i, &i);
+  }
+
+  case 'u':     /* Unicode */
+    if (peek(p, '{')) {
+      /* \u{xxxxxxxx} form */
+      nextc(p);
+      c = read_escape_unicode(p, 8);
+      if (c < 0) return 0;
+      if (nextc(p) != '}') goto eof;
+    }
+    else {
+      c = read_escape_unicode(p, 4);
+      if (c < 0) return 0;
+    }
+  return -c;
+
+  case 'b':/* backspace */
+    return '\010';
+
+  case 's':/* space */
+    return ' ';
+
+  case 'M':
+    if ((c = nextc(p)) != '-') {
+      yyerror(p, "Invalid escape character syntax");
+      pushback(p, c);
+      return '\0';
+    }
+    if ((c = nextc(p)) == '\\') {
+      return read_escape(p) | 0x80;
+    }
+    else if (c < 0) goto eof;
+    else {
+      return ((c & 0xff) | 0x80);
+    }
+
+  case 'C':
+    if ((c = nextc(p)) != '-') {
+      yyerror(p, "Invalid escape character syntax");
+      pushback(p, c);
+      return '\0';
+    }
+  case 'c':
+    if ((c = nextc(p))== '\\') {
+      c = read_escape(p);
+    }
+    else if (c == '?')
+      return 0177;
+    else if (c < 0) goto eof;
+    return c & 0x9f;
+
+    eof:
+  case -1:
+  case -2:                      /* end of a file */
+    yyerror(p, "Invalid escape character syntax");
+    return '\0';
+
+  default:
+    return c;
+  }
+}
+
+static int
+parse_string(parser_state *p)
+{
+  int c;
+  string_type type = (string_type)(intptr_t)p->lex_strterm->car;
+  int nest_level = intn(p->lex_strterm->cdr->car);
+  int beg = intn(p->lex_strterm->cdr->cdr->car);
+  int end = intn(p->lex_strterm->cdr->cdr->cdr);
+  parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL;
+
+  if (beg == 0) beg = -3;       /* should never happen */
+  if (end == 0) end = -3;
+  newtok(p);
+  while ((c = nextc(p)) != end || nest_level != 0) {
+    if (hinf && (c == '\n' || c < 0)) {
+      mrb_bool line_head;
+      tokadd(p, '\n');
+      tokfix(p);
+      p->lineno++;
+      p->column = 0;
+      line_head = hinf->line_head;
+      hinf->line_head = TRUE;
+      if (line_head) {
+        /* check whether end of heredoc */
+        const char *s = tok(p);
+        int len = toklen(p);
+        if (hinf->allow_indent) {
+          while (ISSPACE(*s) && len > 0) {
+            ++s;
+            --len;
+          }
+        }
+        if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) {
+          return tHEREDOC_END;
+        }
+      }
+      if (c < 0) {
+        char buf[256];
+        const char s1[] = "can't find heredoc delimiter \"";
+        const char s2[] = "\" anywhere before EOF";
+
+        if (sizeof(s1)+sizeof(s2)+strlen(hinf->term)+1 >= sizeof(buf)) {
+          yyerror(p, "can't find heredoc delimiter anywhere before EOF");
+        } else {
+          strcpy(buf, s1);
+          strcat(buf, hinf->term);
+          strcat(buf, s2);
+          yyerror(p, buf);
+        }
+        return 0;
+      }
+      pylval.nd = new_str(p, tok(p), toklen(p));
+      return tHD_STRING_MID;
+    }
+    if (c < 0) {
+      yyerror(p, "unterminated string meets end of file");
+      return 0;
+    }
+    else if (c == beg) {
+      nest_level++;
+      p->lex_strterm->cdr->car = nint(nest_level);
+    }
+    else if (c == end) {
+      nest_level--;
+      p->lex_strterm->cdr->car = nint(nest_level);
+    }
+    else if (c == '\\') {
+      c = nextc(p);
+      if (type & STR_FUNC_EXPAND) {
+        if (c == end || c == beg) {
+          tokadd(p, c);
+        }
+        else if (c == '\n') {
+          p->lineno++;
+          p->column = 0;
+          if (type & STR_FUNC_ARRAY) {
+            tokadd(p, '\n');
+          }
+        }
+        else if (type & STR_FUNC_REGEXP) {
+          tokadd(p, '\\');
+          tokadd(p, c);
+        }
+        else if (c == 'u' && peek(p, '{')) {
+          /* \u{xxxx xxxx xxxx} form */
+          nextc(p);
+          while (1) {
+            do c = nextc(p); while (ISSPACE(c));
+            if (c == '}') break;
+            pushback(p, c);
+            c = read_escape_unicode(p, 8);
+            if (c < 0) break;
+            tokadd(p, -c);
+          }
+          if (hinf)
+            hinf->line_head = FALSE;
+        }
+        else {
+          pushback(p, c);
+          tokadd(p, read_escape(p));
+          if (hinf)
+            hinf->line_head = FALSE;
+        }
+      }
+      else {
+        if (c != beg && c != end) {
+          if (c == '\n') {
+            p->lineno++;
+            p->column = 0;
+          }
+          if (!(c == '\\' || ((type & STR_FUNC_ARRAY) && ISSPACE(c)))) {
+            tokadd(p, '\\');
+          }
+        }
+        tokadd(p, c);
+      }
+      continue;
+    }
+    else if ((c == '#') && (type & STR_FUNC_EXPAND)) {
+      c = nextc(p);
+      if (c == '{') {
+        tokfix(p);
+        p->lstate = EXPR_BEG;
+        p->cmd_start = TRUE;
+        pylval.nd = new_str(p, tok(p), toklen(p));
+        if (hinf) {
+          hinf->line_head = FALSE;
+          return tHD_STRING_PART;
+        }
+        return tSTRING_PART;
+      }
+      tokadd(p, '#');
+      pushback(p, c);
+      continue;
+    }
+    if ((type & STR_FUNC_ARRAY) && ISSPACE(c)) {
+      if (toklen(p) == 0) {
+        do {
+          if (c == '\n') {
+            p->lineno++;
+            p->column = 0;
+            heredoc_treat_nextline(p);
+            if (p->parsing_heredoc != NULL) {
+              return tHD_LITERAL_DELIM;
+            }
+          }
+          c = nextc(p);
+        } while (ISSPACE(c));
+        pushback(p, c);
+        return tLITERAL_DELIM;
+      }
+      else {
+        pushback(p, c);
+        tokfix(p);
+        pylval.nd = new_str(p, tok(p), toklen(p));
+        return tSTRING_MID;
+      }
+    }
+    if (c == '\n') {
+      p->lineno++;
+      p->column = 0;
+    }
+    tokadd(p, c);
+  }
+
+  tokfix(p);
+  p->lstate = EXPR_ENDARG;
+  end_strterm(p);
+
+  if (type & STR_FUNC_XQUOTE) {
+    pylval.nd = new_xstr(p, tok(p), toklen(p));
+    return tXSTRING;
+  }
+
+  if (type & STR_FUNC_REGEXP) {
+    int f = 0;
+    int re_opt;
+    char *s = strndup(tok(p), toklen(p));
+    char flags[3];
+    char *flag = flags;
+    char enc = '\0';
+    char *encp;
+    char *dup;
+
+    newtok(p);
+    while (re_opt = nextc(p), re_opt >= 0 && ISALPHA(re_opt)) {
+      switch (re_opt) {
+      case 'i': f |= 1; break;
+      case 'x': f |= 2; break;
+      case 'm': f |= 4; break;
+      case 'u': f |= 16; break;
+      case 'n': f |= 32; break;
+      case 'o': break;
+      default: tokadd(p, re_opt); break;
+      }
+    }
+    pushback(p, re_opt);
+    if (toklen(p)) {
+      char msg[128];
+
+      strcpy(msg, "unknown regexp option");
+      tokfix(p);
+      if (toklen(p) > 1) {
+        strcat(msg, "s");
+      }
+      strcat(msg, " - ");
+      strncat(msg, tok(p), sizeof(msg) - strlen(msg) - 1);
+      yyerror(p, msg);
+    }
+    if (f != 0) {
+      if (f & 1) *flag++ = 'i';
+      if (f & 2) *flag++ = 'x';
+      if (f & 4) *flag++ = 'm';
+      if (f & 16) enc = 'u';
+      if (f & 32) enc = 'n';
+    }
+    if (flag > flags) {
+      dup = strndup(flags, (size_t)(flag - flags));
+    }
+    else {
+      dup = NULL;
+    }
+    if (enc) {
+      encp = strndup(&enc, 1);
+    }
+    else {
+      encp = NULL;
+    }
+    pylval.nd = new_regx(p, s, dup, encp);
+
+    return tREGEXP;
+  }
+  pylval.nd = new_str(p, tok(p), toklen(p));
+
+  return tSTRING;
+}
+
+static int
+number_literal_suffix(parser_state *p)
+{
+  int c, result = 0;
+  node *list = 0;
+  int column = p->column;
+  int mask = NUM_SUFFIX_R|NUM_SUFFIX_I;
+
+  while ((c = nextc(p)) != -1) {
+    list = push(list, (node*)(intptr_t)c);
+
+    if ((mask & NUM_SUFFIX_I) && c == 'i') {
+      result |= (mask & NUM_SUFFIX_I);
+      mask &= ~NUM_SUFFIX_I;
+      /* r after i, rational of complex is disallowed */
+      mask &= ~NUM_SUFFIX_R;
+      continue;
+    }
+    if ((mask & NUM_SUFFIX_R) && c == 'r') {
+      result |= (mask & NUM_SUFFIX_R);
+      mask &= ~NUM_SUFFIX_R;
+      continue;
+    }
+    if (!ISASCII(c) || ISALPHA(c) || c == '_') {
+      p->column = column;
+      if (p->pb) {
+        p->pb = append((node*)list, p->pb);
+      }
+      else {
+        p->pb = list;
+      }
+      return 0;
+    }
+    pushback(p, c);
+    break;
+  }
+  return result;
+}
+
+static int
+heredoc_identifier(parser_state *p)
+{
+  int c;
+  int type = str_heredoc;
+  mrb_bool indent = FALSE;
+  mrb_bool quote = FALSE;
+  node *newnode;
+  parser_heredoc_info *info;
+
+  c = nextc(p);
+  if (ISSPACE(c) || c == '=') {
+    pushback(p, c);
+    return 0;
+  }
+  if (c == '-') {
+    indent = TRUE;
+    c = nextc(p);
+  }
+  if (c == '\'' || c == '"') {
+    int term = c;
+    if (c == '\'')
+      quote = TRUE;
+    newtok(p);
+    while ((c = nextc(p)) >= 0 && c != term) {
+      if (c == '\n') {
+        c = -1;
+        break;
+      }
+      tokadd(p, c);
+    }
+    if (c < 0) {
+      yyerror(p, "unterminated here document identifier");
+      return 0;
+    }
+  }
+  else {
+    if (c < 0) {
+      return 0;                 /* missing here document identifier */
+    }
+    if (! identchar(c)) {
+      pushback(p, c);
+      if (indent) pushback(p, '-');
+      return 0;
+    }
+    newtok(p);
+    do {
+      tokadd(p, c);
+    } while ((c = nextc(p)) >= 0 && identchar(c));
+    pushback(p, c);
+  }
+  tokfix(p);
+  newnode = new_heredoc(p);
+  info = (parser_heredoc_info*)newnode->cdr;
+  info->term = strndup(tok(p), toklen(p));
+  info->term_len = toklen(p);
+  if (! quote)
+    type |= STR_FUNC_EXPAND;
+  info->type = (string_type)type;
+  info->allow_indent = indent;
+  info->line_head = TRUE;
+  info->doc = NULL;
+  p->heredocs_from_nextline = push(p->heredocs_from_nextline, newnode);
+  p->lstate = EXPR_END;
+
+  pylval.nd = newnode;
+  return tHEREDOC_BEG;
+}
+
+static int
+arg_ambiguous(parser_state *p)
+{
+  yywarning(p, "ambiguous first argument; put parentheses or even spaces");
+  return 1;
+}
+
+#include "lex.def"
+
+static int
+parser_yylex(parser_state *p)
+{
+  int32_t c;
+  int nlines = 1;
+  int space_seen = 0;
+  int cmd_state;
+  enum mrb_lex_state_enum last_state;
+  int token_column;
+
+  if (p->lex_strterm) {
+    if (is_strterm_type(p, STR_FUNC_HEREDOC)) {
+      if (p->parsing_heredoc != NULL)
+        return parse_string(p);
+    }
+    else
+      return parse_string(p);
+  }
+  cmd_state = p->cmd_start;
+  p->cmd_start = FALSE;
+  retry:
+  last_state = p->lstate;
+  switch (c = nextc(p)) {
+  case '\004':  /* ^D */
+  case '\032':  /* ^Z */
+  case '\0':    /* NUL */
+  case -1:      /* end of script. */
+    if (p->heredocs_from_nextline)
+      goto maybe_heredoc;
+    return 0;
+
+  /* white spaces */
+  case ' ': case '\t': case '\f': case '\r':
+  case '\13':   /* '\v' */
+    space_seen = 1;
+    goto retry;
+
+  case '#':     /* it's a comment */
+    skip(p, '\n');
+    /* fall through */
+  case -2:      /* end of a file */
+  case '\n':
+  maybe_heredoc:
+    heredoc_treat_nextline(p);
+    p->column = 0;
+    switch (p->lstate) {
+    case EXPR_BEG:
+    case EXPR_FNAME:
+    case EXPR_DOT:
+    case EXPR_CLASS:
+    case EXPR_VALUE:
+      p->lineno++;
+      if (p->parsing_heredoc != NULL) {
+        if (p->lex_strterm) {
+          return parse_string(p);
+        }
+      }
+      goto retry;
+    default:
+      break;
+    }
+    if (p->parsing_heredoc != NULL) {
+      pylval.num = nlines;
+      return '\n';
+    }
+    while ((c = nextc(p))) {
+      switch (c) {
+      case ' ': case '\t': case '\f': case '\r':
+      case '\13': /* '\v' */
+        space_seen = 1;
+        break;
+      case '#': /* comment as a whitespace */
+        skip(p, '\n');
+        nlines++;
+        break;
+      case '.':
+        if (!peek(p, '.')) {
+          pushback(p, '.');
+          p->lineno+=nlines; nlines=1;
+          goto retry;
+        }
+        pushback(p, c);
+        goto normal_newline;
+      case '&':
+        if (peek(p, '.')) {
+          pushback(p, '&');
+          p->lineno+=nlines; nlines=1;
+          goto retry;
+        }
+        pushback(p, c);
+        goto normal_newline;
+      case -1:                  /* EOF */
+      case -2:                  /* end of a file */
+        goto normal_newline;
+      default:
+        pushback(p, c);
+        goto normal_newline;
+      }
+    }
+  normal_newline:
+    p->cmd_start = TRUE;
+    p->lstate = EXPR_BEG;
+    pylval.num = nlines;
+    return '\n';
+
+  case '*':
+    if ((c = nextc(p)) == '*') {
+      if ((c = nextc(p)) == '=') {
+        pylval.id = intern_lit("**");
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      if (IS_SPCARG(c)) {
+        yywarning(p, "'**' interpreted as argument prefix");
+        c = tDSTAR;
+      }
+      else if (IS_BEG()) {
+        c = tDSTAR;
+      }
+      else {
+        c = tPOW; /* "**", "argument prefix" */
+      }
+    }
+    else {
+      if (c == '=') {
+        pylval.id = intern_lit("*");
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      if (IS_SPCARG(c)) {
+        yywarning(p, "'*' interpreted as argument prefix");
+        c = tSTAR;
+      }
+      else if (IS_BEG()) {
+        c = tSTAR;
+      }
+      else {
+        c = '*';
+      }
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    return c;
+
+  case '!':
+    c = nextc(p);
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+      if (c == '@') {
+        return '!';
+      }
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    if (c == '=') {
+      return tNEQ;
+    }
+    if (c == '~') {
+      return tNMATCH;
+    }
+    pushback(p, c);
+    return '!';
+
+  case '=':
+    if (p->column == 1) {
+      static const char begin[] = "begin";
+      static const char end[] = "\n=end";
+      if (peeks(p, begin)) {
+        c = peekc_n(p, sizeof(begin)-1);
+        if (c < 0 || ISSPACE(c)) {
+          do {
+            if (!skips(p, end)) {
+              yyerror(p, "embedded document meets end of file");
+              return 0;
+            }
+            c = nextc(p);
+          } while (!(c < 0 || ISSPACE(c)));
+          if (c != '\n') skip(p, '\n');
+          p->lineno+=nlines; nlines=1;
+          p->column = 0;
+          goto retry;
+        }
+      }
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    if ((c = nextc(p)) == '=') {
+      if ((c = nextc(p)) == '=') {
+        return tEQQ;
+      }
+      pushback(p, c);
+      return tEQ;
+    }
+    if (c == '~') {
+      return tMATCH;
+    }
+    else if (c == '>') {
+      return tASSOC;
+    }
+    pushback(p, c);
+    return '=';
+
+  case '<':
+    c = nextc(p);
+    if (c == '<' &&
+        p->lstate != EXPR_DOT &&
+        p->lstate != EXPR_CLASS &&
+        !IS_END() &&
+        (!IS_ARG() || space_seen)) {
+      int token = heredoc_identifier(p);
+      if (token)
+        return token;
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+      if (p->lstate == EXPR_CLASS) {
+        p->cmd_start = TRUE;
+      }
+    }
+    if (c == '=') {
+      if ((c = nextc(p)) == '>') {
+        return tCMP;
+      }
+      pushback(p, c);
+      return tLEQ;
+    }
+    if (c == '<') {
+      if ((c = nextc(p)) == '=') {
+        pylval.id = intern_lit("<<");
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      return tLSHFT;
+    }
+    pushback(p, c);
+    return '<';
+
+  case '>':
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    if ((c = nextc(p)) == '=') {
+      return tGEQ;
+    }
+    if (c == '>') {
+      if ((c = nextc(p)) == '=') {
+        pylval.id = intern_lit(">>");
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      return tRSHFT;
+    }
+    pushback(p, c);
+    return '>';
+
+  case '"':
+    p->lex_strterm = new_strterm(p, str_dquote, '"', 0);
+    return tSTRING_BEG;
+
+  case '\'':
+    p->lex_strterm = new_strterm(p, str_squote, '\'', 0);
+    return parse_string(p);
+
+  case '`':
+    if (p->lstate == EXPR_FNAME) {
+      p->lstate = EXPR_ENDFN;
+      return '`';
+    }
+    if (p->lstate == EXPR_DOT) {
+      if (cmd_state)
+        p->lstate = EXPR_CMDARG;
+      else
+        p->lstate = EXPR_ARG;
+      return '`';
+    }
+    p->lex_strterm = new_strterm(p, str_xquote, '`', 0);
+    return tXSTRING_BEG;
+
+  case '?':
+    if (IS_END()) {
+      p->lstate = EXPR_VALUE;
+      return '?';
+    }
+    c = nextc(p);
+    if (c < 0) {
+      yyerror(p, "incomplete character syntax");
+      return 0;
+    }
+    if (ISSPACE(c)) {
+      if (!IS_ARG()) {
+        int c2;
+        switch (c) {
+        case ' ':
+          c2 = 's';
+          break;
+        case '\n':
+          c2 = 'n';
+          break;
+        case '\t':
+          c2 = 't';
+          break;
+        case '\v':
+          c2 = 'v';
+          break;
+        case '\r':
+          c2 = 'r';
+          break;
+        case '\f':
+          c2 = 'f';
+          break;
+        default:
+          c2 = 0;
+          break;
+        }
+        if (c2) {
+          char buf[256];
+          char cc[] = { (char)c2, '\0' };
+
+          strcpy(buf, "invalid character syntax; use ?\\");
+          strncat(buf, cc, 2);
+          yyerror(p, buf);
+        }
+      }
+      ternary:
+      pushback(p, c);
+      p->lstate = EXPR_VALUE;
+      return '?';
+    }
+    newtok(p);
+    /* need support UTF-8 if configured */
+    if ((ISALNUM(c) || c == '_')) {
+      int c2 = nextc(p);
+      pushback(p, c2);
+      if ((ISALNUM(c2) || c2 == '_')) {
+        goto ternary;
+      }
+    }
+    if (c == '\\') {
+      c = read_escape(p);
+      tokadd(p, c);
+    }
+    else {
+      tokadd(p, c);
+    }
+    tokfix(p);
+    pylval.nd = new_str(p, tok(p), toklen(p));
+    p->lstate = EXPR_ENDARG;
+    return tCHAR;
+
+  case '&':
+    if ((c = nextc(p)) == '&') {
+      p->lstate = EXPR_BEG;
+      if ((c = nextc(p)) == '=') {
+        pylval.id = intern_lit("&&");
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      return tANDOP;
+    }
+    else if (c == '.') {
+      p->lstate = EXPR_DOT;
+      return tANDDOT;
+    }
+    else if (c == '=') {
+      pylval.id = intern_lit("&");
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    pushback(p, c);
+    if (IS_SPCARG(c)) {
+      yywarning(p, "'&' interpreted as argument prefix");
+      c = tAMPER;
+    }
+    else if (IS_BEG()) {
+      c = tAMPER;
+    }
+    else {
+      c = '&';
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    return c;
+
+  case '|':
+    if ((c = nextc(p)) == '|') {
+      p->lstate = EXPR_BEG;
+      if ((c = nextc(p)) == '=') {
+        pylval.id = intern_lit("||");
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      return tOROP;
+    }
+    if (c == '=') {
+      pylval.id = intern_lit("|");
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    pushback(p, c);
+    return '|';
+
+  case '+':
+    c = nextc(p);
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+      if (c == '@') {
+        return tUPLUS;
+      }
+      pushback(p, c);
+      return '+';
+    }
+    if (c == '=') {
+      pylval.id = intern_lit("+");
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) {
+      p->lstate = EXPR_BEG;
+      pushback(p, c);
+      if (c >= 0 && ISDIGIT(c)) {
+        c = '+';
+        goto start_num;
+      }
+      return tUPLUS;
+    }
+    p->lstate = EXPR_BEG;
+    pushback(p, c);
+    return '+';
+
+  case '-':
+    c = nextc(p);
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+      if (c == '@') {
+        return tUMINUS;
+      }
+      pushback(p, c);
+      return '-';
+    }
+    if (c == '=') {
+      pylval.id = intern_lit("-");
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    if (c == '>') {
+      p->lstate = EXPR_ENDFN;
+      return tLAMBDA;
+    }
+    if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) {
+      p->lstate = EXPR_BEG;
+      pushback(p, c);
+      if (c >= 0 && ISDIGIT(c)) {
+        return tUMINUS_NUM;
+      }
+      return tUMINUS;
+    }
+    p->lstate = EXPR_BEG;
+    pushback(p, c);
+    return '-';
+
+  case '.':
+    p->lstate = EXPR_BEG;
+    if ((c = nextc(p)) == '.') {
+      if ((c = nextc(p)) == '.') {
+        return tDOT3;
+      }
+      pushback(p, c);
+      return tDOT2;
+    }
+    pushback(p, c);
+    if (c >= 0 && ISDIGIT(c)) {
+      yyerror(p, "no .<digit> floating literal anymore; put 0 before dot");
+    }
+    p->lstate = EXPR_DOT;
+    return '.';
+
+    start_num:
+  case '0': case '1': case '2': case '3': case '4':
+  case '5': case '6': case '7': case '8': case '9':
+  {
+    int is_float, seen_point, seen_e, nondigit;
+    int suffix = 0;
+
+    is_float = seen_point = seen_e = nondigit = 0;
+    p->lstate = EXPR_ENDARG;
+    newtok(p);
+    if (c == '-' || c == '+') {
+      tokadd(p, c);
+      c = nextc(p);
+    }
+    if (c == '0') {
+#define no_digits() do {yyerror(p,"numeric literal without digits"); return 0;} while (0)
+      int start = toklen(p);
+      c = nextc(p);
+      if (c == 'x' || c == 'X') {
+        /* hexadecimal */
+        c = nextc(p);
+        if (c >= 0 && ISXDIGIT(c)) {
+          do {
+            if (c == '_') {
+              if (nondigit) break;
+              nondigit = c;
+              continue;
+            }
+            if (!ISXDIGIT(c)) break;
+            nondigit = 0;
+            tokadd(p, tolower(c));
+          } while ((c = nextc(p)) >= 0);
+        }
+        pushback(p, c);
+        tokfix(p);
+        if (toklen(p) == start) {
+          no_digits();
+        }
+        else if (nondigit) goto trailing_uc;
+        suffix = number_literal_suffix(p);
+        pylval.nd = new_int(p, tok(p), 16, suffix);
+        return tINTEGER;
+      }
+      if (c == 'b' || c == 'B') {
+        /* binary */
+        c = nextc(p);
+        if (c == '0' || c == '1') {
+          do {
+            if (c == '_') {
+              if (nondigit) break;
+              nondigit = c;
+              continue;
+            }
+            if (c != '0' && c != '1') break;
+            nondigit = 0;
+            tokadd(p, c);
+          } while ((c = nextc(p)) >= 0);
+        }
+        pushback(p, c);
+        tokfix(p);
+        if (toklen(p) == start) {
+          no_digits();
+        }
+        else if (nondigit) goto trailing_uc;
+        suffix = number_literal_suffix(p);
+        pylval.nd = new_int(p, tok(p), 2, suffix);
+        return tINTEGER;
+      }
+      if (c == 'd' || c == 'D') {
+        /* decimal */
+        c = nextc(p);
+        if (c >= 0 && ISDIGIT(c)) {
+          do {
+            if (c == '_') {
+              if (nondigit) break;
+              nondigit = c;
+              continue;
+            }
+            if (!ISDIGIT(c)) break;
+            nondigit = 0;
+            tokadd(p, c);
+          } while ((c = nextc(p)) >= 0);
+        }
+        pushback(p, c);
+        tokfix(p);
+        if (toklen(p) == start) {
+          no_digits();
+        }
+        else if (nondigit) goto trailing_uc;
+        suffix = number_literal_suffix(p);
+        pylval.nd = new_int(p, tok(p), 10, suffix);
+        return tINTEGER;
+      }
+      if (c == '_') {
+        /* 0_0 */
+        goto octal_number;
+      }
+      if (c == 'o' || c == 'O') {
+        /* prefixed octal */
+        c = nextc(p);
+        if (c < 0 || c == '_' || !ISDIGIT(c)) {
+          no_digits();
+        }
+      }
+      if (c >= '0' && c <= '7') {
+        /* octal */
+        octal_number:
+        do {
+          if (c == '_') {
+            if (nondigit) break;
+            nondigit = c;
+            continue;
+          }
+          if (c < '0' || c > '9') break;
+          if (c > '7') goto invalid_octal;
+          nondigit = 0;
+          tokadd(p, c);
+        } while ((c = nextc(p)) >= 0);
+
+        if (toklen(p) > start) {
+          pushback(p, c);
+          tokfix(p);
+          if (nondigit) goto trailing_uc;
+          suffix = number_literal_suffix(p);
+          pylval.nd = new_int(p, tok(p), 8, suffix);
+          return tINTEGER;
+        }
+        if (nondigit) {
+          pushback(p, c);
+          goto trailing_uc;
+        }
+      }
+      if (c > '7' && c <= '9') {
+        invalid_octal:
+        yyerror(p, "Invalid octal digit");
+      }
+      else if (c == '.' || c == 'e' || c == 'E') {
+        tokadd(p, '0');
+      }
+      else {
+        pushback(p, c);
+        suffix = number_literal_suffix(p);
+        pylval.nd = new_int(p, "0", 10, suffix);
+        return tINTEGER;
+      }
+    }
+
+    for (;;) {
+      switch (c) {
+      case '0': case '1': case '2': case '3': case '4':
+      case '5': case '6': case '7': case '8': case '9':
+        nondigit = 0;
+        tokadd(p, c);
+        break;
+
+      case '.':
+        if (nondigit) goto trailing_uc;
+        if (seen_point || seen_e) {
+          goto decode_num;
+        }
+        else {
+          int c0 = nextc(p);
+          if (c0 < 0 || !ISDIGIT(c0)) {
+            pushback(p, c0);
+            goto decode_num;
+          }
+          c = c0;
+        }
+        tokadd(p, '.');
+        tokadd(p, c);
+        is_float++;
+        seen_point++;
+        nondigit = 0;
+        break;
+
+      case 'e':
+      case 'E':
+        if (nondigit) {
+          pushback(p, c);
+          c = nondigit;
+          goto decode_num;
+        }
+        if (seen_e) {
+          goto decode_num;
+        }
+        tokadd(p, c);
+        seen_e++;
+        is_float++;
+        nondigit = c;
+        c = nextc(p);
+        if (c != '-' && c != '+') continue;
+        tokadd(p, c);
+        nondigit = c;
+        break;
+
+      case '_':       /* '_' in number just ignored */
+        if (nondigit) goto decode_num;
+        nondigit = c;
+        break;
+
+      default:
+        goto decode_num;
+      }
+      c = nextc(p);
+    }
+
+    decode_num:
+    pushback(p, c);
+    if (nondigit) {
+      trailing_uc:
+      yyerror_c(p, "trailing non digit in number: ", (char)nondigit);
+    }
+    tokfix(p);
+    if (is_float) {
+#ifdef MRB_WITHOUT_FLOAT
+      yywarning_s(p, "floating point numbers are not supported", tok(p));
+      pylval.nd = new_int(p, "0", 10, 0);
+      return tINTEGER;
+#else
+      double d;
+      char *endp;
+
+      errno = 0;
+      d = mrb_float_read(tok(p), &endp);
+      if (d == 0 && endp == tok(p)) {
+        yywarning_s(p, "corrupted float value", tok(p));
+      }
+      else if (errno == ERANGE) {
+        yywarning_s(p, "float out of range", tok(p));
+        errno = 0;
+      }
+      suffix = number_literal_suffix(p);
+      pylval.nd = new_float(p, tok(p), suffix);
+      return tFLOAT;
+#endif
+    }
+    suffix = number_literal_suffix(p);
+    pylval.nd = new_int(p, tok(p), 10, suffix);
+    return tINTEGER;
+  }
+
+  case ')':
+  case ']':
+    p->paren_nest--;
+    /* fall through */
+  case '}':
+    COND_LEXPOP();
+    CMDARG_LEXPOP();
+    if (c == ')')
+      p->lstate = EXPR_ENDFN;
+    else
+      p->lstate = EXPR_END;
+    return c;
+
+  case ':':
+    c = nextc(p);
+    if (c == ':') {
+      if (IS_BEG() || p->lstate == EXPR_CLASS || IS_SPCARG(-1)) {
+        p->lstate = EXPR_BEG;
+        return tCOLON3;
+      }
+      p->lstate = EXPR_DOT;
+      return tCOLON2;
+    }
+    if (!space_seen && IS_END()) {
+      pushback(p, c);
+      p->lstate = EXPR_BEG;
+      return tLABEL_TAG;
+    }
+    if (!ISSPACE(c) || IS_BEG()) {
+      pushback(p, c);
+      p->lstate = EXPR_FNAME;
+      return tSYMBEG;
+    }
+    pushback(p, c);
+    p->lstate = EXPR_BEG;
+    return ':';
+
+  case '/':
+    if (IS_BEG()) {
+      p->lex_strterm = new_strterm(p, str_regexp, '/', 0);
+      return tREGEXP_BEG;
+    }
+    if ((c = nextc(p)) == '=') {
+      pylval.id = intern_lit("/");
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    pushback(p, c);
+    if (IS_SPCARG(c)) {
+      p->lex_strterm = new_strterm(p, str_regexp, '/', 0);
+      return tREGEXP_BEG;
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    return '/';
+
+  case '^':
+    if ((c = nextc(p)) == '=') {
+      pylval.id = intern_lit("^");
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    pushback(p, c);
+    return '^';
+
+  case ';':
+    p->lstate = EXPR_BEG;
+    return ';';
+
+  case ',':
+    p->lstate = EXPR_BEG;
+    return ',';
+
+  case '~':
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      if ((c = nextc(p)) != '@') {
+        pushback(p, c);
+      }
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    return '~';
+
+  case '(':
+    if (IS_BEG()) {
+      c = tLPAREN;
+    }
+    else if (IS_SPCARG(-1)) {
+      c = tLPAREN_ARG;
+    }
+    else if (p->lstate == EXPR_END && space_seen) {
+      c = tLPAREN_ARG;
+    }
+    p->paren_nest++;
+    COND_PUSH(0);
+    CMDARG_PUSH(0);
+    p->lstate = EXPR_BEG;
+    return c;
+
+  case '[':
+    p->paren_nest++;
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+      if ((c = nextc(p)) == ']') {
+        if ((c = nextc(p)) == '=') {
+          return tASET;
+        }
+        pushback(p, c);
+        return tAREF;
+      }
+      pushback(p, c);
+      return '[';
+    }
+    else if (IS_BEG()) {
+      c = tLBRACK;
+    }
+    else if (IS_ARG() && space_seen) {
+      c = tLBRACK;
+    }
+    p->lstate = EXPR_BEG;
+    COND_PUSH(0);
+    CMDARG_PUSH(0);
+    return c;
+
+  case '{':
+    if (p->lpar_beg && p->lpar_beg == p->paren_nest) {
+      p->lstate = EXPR_BEG;
+      p->lpar_beg = 0;
+      p->paren_nest--;
+      COND_PUSH(0);
+      CMDARG_PUSH(0);
+      return tLAMBEG;
+    }
+    if (IS_ARG() || p->lstate == EXPR_END || p->lstate == EXPR_ENDFN)
+      c = '{';          /* block (primary) */
+    else if (p->lstate == EXPR_ENDARG)
+      c = tLBRACE_ARG;  /* block (expr) */
+    else
+      c = tLBRACE;      /* hash */
+    COND_PUSH(0);
+    CMDARG_PUSH(0);
+    p->lstate = EXPR_BEG;
+    return c;
+
+  case '\\':
+    c = nextc(p);
+    if (c == '\n') {
+      p->lineno+=nlines; nlines=1;
+      p->column = 0;
+      space_seen = 1;
+      goto retry; /* skip \\n */
+    }
+    pushback(p, c);
+    return '\\';
+
+  case '%':
+    if (IS_BEG()) {
+      int term;
+      int paren;
+
+      c = nextc(p);
+      quotation:
+      if (c < 0 || !ISALNUM(c)) {
+        term = c;
+        c = 'Q';
+      }
+      else {
+        term = nextc(p);
+        if (ISALNUM(term)) {
+          yyerror(p, "unknown type of %string");
+          return 0;
+        }
+      }
+      if (c < 0 || term < 0) {
+        yyerror(p, "unterminated quoted string meets end of file");
+        return 0;
+      }
+      paren = term;
+      if (term == '(') term = ')';
+      else if (term == '[') term = ']';
+      else if (term == '{') term = '}';
+      else if (term == '<') term = '>';
+      else paren = 0;
+
+      switch (c) {
+      case 'Q':
+        p->lex_strterm = new_strterm(p, str_dquote, term, paren);
+        return tSTRING_BEG;
+
+      case 'q':
+        p->lex_strterm = new_strterm(p, str_squote, term, paren);
+        return parse_string(p);
+
+      case 'W':
+        p->lex_strterm = new_strterm(p, str_dword, term, paren);
+        return tWORDS_BEG;
+
+      case 'w':
+        p->lex_strterm = new_strterm(p, str_sword, term, paren);
+        return tWORDS_BEG;
+
+      case 'x':
+        p->lex_strterm = new_strterm(p, str_xquote, term, paren);
+        return tXSTRING_BEG;
+
+      case 'r':
+        p->lex_strterm = new_strterm(p, str_regexp, term, paren);
+        return tREGEXP_BEG;
+
+      case 's':
+        p->lex_strterm = new_strterm(p, str_ssym, term, paren);
+        return tSYMBEG;
+
+      case 'I':
+        p->lex_strterm = new_strterm(p, str_dsymbols, term, paren);
+        return tSYMBOLS_BEG;
+
+      case 'i':
+        p->lex_strterm = new_strterm(p, str_ssymbols, term, paren);
+        return tSYMBOLS_BEG;
+
+      default:
+        yyerror(p, "unknown type of %string");
+        return 0;
+      }
+    }
+    if ((c = nextc(p)) == '=') {
+      pylval.id = intern_lit("%");
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    if (IS_SPCARG(c)) {
+      goto quotation;
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    pushback(p, c);
+    return '%';
+
+  case '$':
+    p->lstate = EXPR_END;
+    token_column = newtok(p);
+    c = nextc(p);
+    if (c < 0) {
+      yyerror(p, "incomplete global variable syntax");
+      return 0;
+    }
+    switch (c) {
+    case '_':     /* $_: last read line string */
+      c = nextc(p);
+      if (c >= 0 && identchar(c)) { /* if there is more after _ it is a variable */
+        tokadd(p, '$');
+        tokadd(p, c);
+        break;
+      }
+      pushback(p, c);
+      c = '_';
+      /* fall through */
+    case '~':     /* $~: match-data */
+    case '*':     /* $*: argv */
+    case '$':     /* $$: pid */
+    case '?':     /* $?: last status */
+    case '!':     /* $!: error string */
+    case '@':     /* $@: error position */
+    case '/':     /* $/: input record separator */
+    case '\\':    /* $\: output record separator */
+    case ';':     /* $;: field separator */
+    case ',':     /* $,: output field separator */
+    case '.':     /* $.: last read line number */
+    case '=':     /* $=: ignorecase */
+    case ':':     /* $:: load path */
+    case '<':     /* $<: reading filename */
+    case '>':     /* $>: default output handle */
+    case '\"':    /* $": already loaded files */
+      tokadd(p, '$');
+      tokadd(p, c);
+      tokfix(p);
+      pylval.id = intern(tok(p), toklen(p));
+      return tGVAR;
+
+    case '-':
+      tokadd(p, '$');
+      tokadd(p, c);
+      c = nextc(p);
+      pushback(p, c);
+      gvar:
+      tokfix(p);
+      pylval.id = intern(tok(p), toklen(p));
+      return tGVAR;
+
+    case '&':     /* $&: last match */
+    case '`':     /* $`: string before last match */
+    case '\'':    /* $': string after last match */
+    case '+':     /* $+: string matches last pattern */
+      if (last_state == EXPR_FNAME) {
+        tokadd(p, '$');
+        tokadd(p, c);
+        goto gvar;
+      }
+      pylval.nd = new_back_ref(p, c);
+      return tBACK_REF;
+
+    case '1': case '2': case '3':
+    case '4': case '5': case '6':
+    case '7': case '8': case '9':
+      do {
+        tokadd(p, c);
+        c = nextc(p);
+      } while (c >= 0 && ISDIGIT(c));
+      pushback(p, c);
+      if (last_state == EXPR_FNAME) goto gvar;
+      tokfix(p);
+      {
+        unsigned long n = strtoul(tok(p), NULL, 10);
+        if (n > INT_MAX) {
+          yyerror(p, "capture group index must be <= " MRB_STRINGIZE(INT_MAX));
+          return 0;
+        }
+        pylval.nd = new_nth_ref(p, (int)n);
+      }
+      return tNTH_REF;
+
+    default:
+      if (!identchar(c)) {
+        pushback(p,  c);
+        return '$';
+      }
+      /* fall through */
+    case '0':
+      tokadd(p, '$');
+    }
+    break;
+
+    case '@':
+      c = nextc(p);
+      token_column = newtok(p);
+      tokadd(p, '@');
+      if (c == '@') {
+        tokadd(p, '@');
+        c = nextc(p);
+      }
+      if (c < 0) {
+        if (p->tidx == 1) {
+          yyerror(p, "incomplete instance variable syntax");
+        }
+        else {
+          yyerror(p, "incomplete class variable syntax");
+        }
+        return 0;
+      }
+      else if (ISDIGIT(c)) {
+        if (p->tidx == 1) {
+          yyerror_c(p, "wrong instance variable name: @", c);
+        }
+        else {
+          yyerror_c(p, "wrong class variable name: @@", c);
+        }
+        return 0;
+      }
+      if (!identchar(c)) {
+        pushback(p, c);
+        return '@';
+      }
+      break;
+
+    case '_':
+      token_column = newtok(p);
+      break;
+
+    default:
+      if (!identchar(c)) {
+        char buf[36];
+        const char s[] = "Invalid char in expression: 0x";
+        const char hexdigits[] = "0123456789ABCDEF";
+
+        strcpy(buf, s);
+        buf[sizeof(s)-1] = hexdigits[(c & 0xf0) >> 4];
+        buf[sizeof(s)]   = hexdigits[(c & 0x0f)];
+        buf[sizeof(s)+1] = 0;
+        yyerror(p, buf);
+        goto retry;
+      }
+
+      token_column = newtok(p);
+      break;
+  }
+
+  do {
+    tokadd(p, c);
+    c = nextc(p);
+    if (c < 0) break;
+  } while (identchar(c));
+  if (token_column == 0 && toklen(p) == 7 && (c < 0 || c == '\n') &&
+      strncmp(tok(p), "__END__", toklen(p)) == 0)
+    return -1;
+
+  switch (tok(p)[0]) {
+  case '@': case '$':
+    pushback(p, c);
+    break;
+  default:
+    if ((c == '!' || c == '?') && !peek(p, '=')) {
+      tokadd(p, c);
+    }
+    else {
+      pushback(p, c);
+    }
+  }
+  tokfix(p);
+  {
+    int result = 0;
+
+    switch (tok(p)[0]) {
+    case '$':
+      p->lstate = EXPR_END;
+      result = tGVAR;
+      break;
+    case '@':
+      p->lstate = EXPR_END;
+      if (tok(p)[1] == '@')
+        result = tCVAR;
+      else
+        result = tIVAR;
+      break;
+
+    case '_':
+      if (toklen(p) == 2 && ISDIGIT(tok(p)[1]) && p->nvars) {
+        int n = tok(p)[1] - '0';
+        int nvar;
+
+        if (n > 0) {
+          node *nvars = p->nvars->cdr;
+
+          while (nvars) {
+            nvar = intn(nvars->car);
+            if (nvar == -2) break; /* top of the scope */
+            if (nvar > 0) {
+              yywarning(p, "numbered parameter used in outer block");
+              break;
+            }
+            nvars->car = nint(-1);
+            nvars = nvars->cdr;
+          }
+          nvar = intn(p->nvars->car);
+          if (nvar == -1) {
+            yywarning(p, "numbered parameter used in inner block");
+          }
+          if (nvar >= -1) {
+            pylval.num = n;
+            p->lstate = EXPR_END;
+            return tNUMPARAM;
+          }
+          else {
+            yywarning(p, "identifier for numbered parameter; consider another name");
+          }
+        }
+      }
+      /* fall through */
+    default:
+      if (toklast(p) == '!' || toklast(p) == '?') {
+        result = tFID;
+      }
+      else {
+        if (p->lstate == EXPR_FNAME) {
+          if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
+              (!peek(p, '=') || (peek_n(p, '>', 1)))) {
+            result = tIDENTIFIER;
+            tokadd(p, c);
+            tokfix(p);
+          }
+          else {
+            pushback(p, c);
+          }
+          if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
+              (!peek(p, '=') || (peek_n(p, '>', 1)))) {
+            result = tIDENTIFIER;
+            tokadd(p, c);
+            tokfix(p);
+          }
+          else {
+            pushback(p, c);
+          }
+        }
+        if (result == 0 && ISUPPER(tok(p)[0])) {
+          result = tCONSTANT;
+        }
+        else {
+          result = tIDENTIFIER;
+        }
+      }
+
+      if (IS_LABEL_POSSIBLE()) {
+        if (IS_LABEL_SUFFIX(0)) {
+          p->lstate = EXPR_END;
+          tokfix(p);
+          pylval.id = intern(tok(p), toklen(p));
+          return tIDENTIFIER;
+        }
+      }
+      if (p->lstate != EXPR_DOT) {
+        const struct kwtable *kw;
+
+        /* See if it is a reserved word.  */
+        kw = mrb_reserved_word(tok(p), toklen(p));
+        if (kw) {
+          enum mrb_lex_state_enum state = p->lstate;
+          pylval.num = p->lineno;
+          p->lstate = kw->state;
+          if (state == EXPR_FNAME) {
+            pylval.id = intern_cstr(kw->name);
+            return kw->id[0];
+          }
+          if (p->lstate == EXPR_BEG) {
+            p->cmd_start = TRUE;
+          }
+          if (kw->id[0] == keyword_do) {
+            if (p->lpar_beg && p->lpar_beg == p->paren_nest) {
+              p->lpar_beg = 0;
+              p->paren_nest--;
+              return keyword_do_LAMBDA;
+            }
+            if (COND_P()) return keyword_do_cond;
+            if (CMDARG_P() && state != EXPR_CMDARG)
+              return keyword_do_block;
+            if (state == EXPR_ENDARG || state == EXPR_BEG)
+              return keyword_do_block;
+            return keyword_do;
+          }
+          if (state == EXPR_BEG || state == EXPR_VALUE)
+            return kw->id[0];
+          else {
+            if (kw->id[0] != kw->id[1])
+              p->lstate = EXPR_BEG;
+            return kw->id[1];
+          }
+        }
+      }
+
+      if (IS_BEG() || p->lstate == EXPR_DOT || IS_ARG()) {
+        if (cmd_state) {
+          p->lstate = EXPR_CMDARG;
+        }
+        else {
+          p->lstate = EXPR_ARG;
+        }
+      }
+      else if (p->lstate == EXPR_FNAME) {
+        p->lstate = EXPR_ENDFN;
+      }
+      else {
+        p->lstate = EXPR_END;
+      }
+    }
+    {
+      mrb_sym ident = intern(tok(p), toklen(p));
+
+      pylval.id = ident;
+      if (last_state != EXPR_DOT && ISLOWER(tok(p)[0]) && local_var_p(p, ident)) {
+        p->lstate = EXPR_END;
+      }
+    }
+    return result;
+  }
+}
+
+static int
+yylex(void *lval, parser_state *p)
+{
+  p->ylval = lval;
+  return parser_yylex(p);
+}
+
+static void
+parser_init_cxt(parser_state *p, mrbc_context *cxt)
+{
+  if (!cxt) return;
+  if (cxt->filename) mrb_parser_set_filename(p, cxt->filename);
+  if (cxt->lineno) p->lineno = cxt->lineno;
+  if (cxt->syms) {
+    int i;
+
+    p->locals = cons(0,0);
+    for (i=0; i<cxt->slen; i++) {
+      local_add_f(p, cxt->syms[i]);
+    }
+  }
+  p->capture_errors = cxt->capture_errors;
+  p->no_optimize = cxt->no_optimize;
+  p->upper = cxt->upper;
+  if (cxt->partial_hook) {
+    p->cxt = cxt;
+  }
+}
+
+static void
+parser_update_cxt(parser_state *p, mrbc_context *cxt)
+{
+  node *n, *n0;
+  int i = 0;
+
+  if (!cxt) return;
+  if (intn(p->tree->car) != NODE_SCOPE) return;
+  n0 = n = p->tree->cdr->car;
+  while (n) {
+    i++;
+    n = n->cdr;
+  }
+  cxt->syms = (mrb_sym *)mrb_realloc(p->mrb, cxt->syms, i*sizeof(mrb_sym));
+  cxt->slen = i;
+  for (i=0, n=n0; n; i++,n=n->cdr) {
+    cxt->syms[i] = sym(n->car);
+  }
+}
+
+void mrb_codedump_all(mrb_state*, struct RProc*);
+void mrb_parser_dump(mrb_state *mrb, node *tree, int offset);
+
+MRB_API void
+mrb_parser_parse(parser_state *p, mrbc_context *c)
+{
+  struct mrb_jmpbuf buf1;
+  p->jmp = &buf1;
+
+  MRB_TRY(p->jmp) {
+    int n = 1;
+
+    p->cmd_start = TRUE;
+    p->in_def = p->in_single = 0;
+    p->nerr = p->nwarn = 0;
+    p->lex_strterm = NULL;
+
+    parser_init_cxt(p, c);
+
+    if (p->mrb->jmp) {
+      n = yyparse(p);
+    }
+    else {
+      struct mrb_jmpbuf buf2;
+
+      p->mrb->jmp = &buf2;
+      MRB_TRY(p->mrb->jmp) {
+        n = yyparse(p);
+      }
+      MRB_CATCH(p->mrb->jmp) {
+        p->nerr++;
+      }
+      MRB_END_EXC(p->mrb->jmp);
+      p->mrb->jmp = 0;
+    }
+    if (n != 0 || p->nerr > 0) {
+      p->tree = 0;
+      return;
+    }
+    if (!p->tree) {
+      p->tree = new_nil(p);
+    }
+    parser_update_cxt(p, c);
+    if (c && c->dump_result) {
+      mrb_parser_dump(p->mrb, p->tree, 0);
+    }
+  }
+  MRB_CATCH(p->jmp) {
+    yyerror(p, "memory allocation error");
+    p->nerr++;
+    p->tree = 0;
+    return;
+  }
+  MRB_END_EXC(p->jmp);
+}
+
+MRB_API parser_state*
+mrb_parser_new(mrb_state *mrb)
+{
+  mrb_pool *pool;
+  parser_state *p;
+  static const parser_state parser_state_zero = { 0 };
+
+  pool = mrb_pool_open(mrb);
+  if (!pool) return NULL;
+  p = (parser_state *)mrb_pool_alloc(pool, sizeof(parser_state));
+  if (!p) return NULL;
+
+  *p = parser_state_zero;
+  p->mrb = mrb;
+  p->pool = pool;
+
+  p->s = p->send = NULL;
+#ifndef MRB_DISABLE_STDIO
+  p->f = NULL;
+#endif
+
+  p->cmd_start = TRUE;
+  p->in_def = p->in_single = 0;
+
+  p->capture_errors = FALSE;
+  p->lineno = 1;
+  p->column = 0;
+#if defined(PARSER_TEST) || defined(PARSER_DEBUG)
+  yydebug = 1;
+#endif
+  p->tsiz = MRB_PARSER_TOKBUF_SIZE;
+  p->tokbuf = p->buf;
+
+  p->lex_strterm = NULL;
+  p->all_heredocs = p->parsing_heredoc = NULL;
+  p->lex_strterm_before_heredoc = NULL;
+
+  p->current_filename_index = -1;
+  p->filename_table = NULL;
+  p->filename_table_length = 0;
+
+  return p;
+}
+
+MRB_API void
+mrb_parser_free(parser_state *p) {
+  if (p->tokbuf != p->buf) {
+    mrb_free(p->mrb, p->tokbuf);
+  }
+  mrb_pool_close(p->pool);
+}
+
+MRB_API mrbc_context*
+mrbc_context_new(mrb_state *mrb)
+{
+  return (mrbc_context *)mrb_calloc(mrb, 1, sizeof(mrbc_context));
+}
+
+MRB_API void
+mrbc_context_free(mrb_state *mrb, mrbc_context *cxt)
+{
+  mrb_free(mrb, cxt->filename);
+  mrb_free(mrb, cxt->syms);
+  mrb_free(mrb, cxt);
+}
+
+MRB_API const char*
+mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s)
+{
+  if (s) {
+    size_t len = strlen(s);
+    char *p = (char *)mrb_malloc(mrb, len + 1);
+
+    memcpy(p, s, len + 1);
+    if (c->filename) {
+      mrb_free(mrb, c->filename);
+    }
+    c->filename = p;
+  }
+  return c->filename;
+}
+
+MRB_API void
+mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*func)(struct mrb_parser_state*), void *data)
+{
+  c->partial_hook = func;
+  c->partial_data = data;
+}
+
+MRB_API void
+mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
+{
+  mrb_sym sym;
+  size_t i;
+  mrb_sym* new_table;
+
+  sym = mrb_intern_cstr(p->mrb, f);
+  p->filename_sym = sym;
+  p->lineno = (p->filename_table_length > 0)? 0 : 1;
+
+  for (i = 0; i < p->filename_table_length; ++i) {
+    if (p->filename_table[i] == sym) {
+      p->current_filename_index = (int)i;
+      return;
+    }
+  }
+
+  if (p->filename_table_length == UINT16_MAX) {
+    yyerror(p, "too many files to compile");
+    return;
+  }
+  p->current_filename_index = p->filename_table_length++;
+
+  new_table = (mrb_sym*)parser_palloc(p, sizeof(mrb_sym) * p->filename_table_length);
+  if (p->filename_table) {
+    memmove(new_table, p->filename_table, sizeof(mrb_sym) * p->current_filename_index);
+  }
+  p->filename_table = new_table;
+  p->filename_table[p->filename_table_length - 1] = sym;
+}
+
+MRB_API mrb_sym
+mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
+  if (idx >= p->filename_table_length) return 0;
+  else {
+    return p->filename_table[idx];
+  }
+}
+
+#ifndef MRB_DISABLE_STDIO
+MRB_API parser_state*
+mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
+{
+  parser_state *p;
+
+  p = mrb_parser_new(mrb);
+  if (!p) return NULL;
+  p->s = p->send = NULL;
+  p->f = f;
+
+  mrb_parser_parse(p, c);
+  return p;
+}
+#endif
+
+MRB_API parser_state*
+mrb_parse_nstring(mrb_state *mrb, const char *s, size_t len, mrbc_context *c)
+{
+  parser_state *p;
+
+  p = mrb_parser_new(mrb);
+  if (!p) return NULL;
+  p->s = s;
+  p->send = s + len;
+
+  mrb_parser_parse(p, c);
+  return p;
+}
+
+MRB_API parser_state*
+mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c)
+{
+  return mrb_parse_nstring(mrb, s, strlen(s), c);
+}
+
+MRB_API mrb_value
+mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
+{
+  struct RClass *target = mrb->object_class;
+  struct RProc *proc;
+  mrb_value v;
+  unsigned int keep = 0;
+
+  if (!p) {
+    return mrb_undef_value();
+  }
+  if (!p->tree || p->nerr) {
+    if (c) c->parser_nerr = p->nerr;
+    if (p->capture_errors) {
+      char buf[256];
+
+      strcpy(buf, "line ");
+      dump_int(p->error_buffer[0].lineno, buf+5);
+      strcat(buf, ": ");
+      strncat(buf, p->error_buffer[0].message, sizeof(buf) - strlen(buf) - 1);
+      mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, strlen(buf)));
+      mrb_parser_free(p);
+      return mrb_undef_value();
+    }
+    else {
+      if (mrb->exc == NULL) {
+        mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SYNTAX_ERROR, "syntax error"));
+      }
+      mrb_parser_free(p);
+      return mrb_undef_value();
+    }
+  }
+  proc = mrb_generate_code(mrb, p);
+  mrb_parser_free(p);
+  if (proc == NULL) {
+    if (mrb->exc == NULL) {
+      mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "codegen error"));
+    }
+    return mrb_undef_value();
+  }
+  if (c) {
+    if (c->dump_result) mrb_codedump_all(mrb, proc);
+    if (c->no_exec) return mrb_obj_value(proc);
+    if (c->target_class) {
+      target = c->target_class;
+    }
+    if (c->keep_lv) {
+      keep = c->slen + 1;
+    }
+    else {
+      c->keep_lv = TRUE;
+    }
+  }
+  MRB_PROC_SET_TARGET_CLASS(proc, target);
+  if (mrb->c->ci) {
+    mrb->c->ci->target_class = target;
+  }
+  v = mrb_top_run(mrb, proc, mrb_top_self(mrb), keep);
+  if (mrb->exc) return mrb_nil_value();
+  return v;
+}
+
+#ifndef MRB_DISABLE_STDIO
+MRB_API mrb_value
+mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c)
+{
+  return mrb_load_exec(mrb, mrb_parse_file(mrb, f, c), c);
+}
+
+MRB_API mrb_value
+mrb_load_file(mrb_state *mrb, FILE *f)
+{
+  return mrb_load_file_cxt(mrb, f, NULL);
+}
+#endif
+
+MRB_API mrb_value
+mrb_load_nstring_cxt(mrb_state *mrb, const char *s, size_t len, mrbc_context *c)
+{
+  return mrb_load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c);
+}
+
+MRB_API mrb_value
+mrb_load_nstring(mrb_state *mrb, const char *s, size_t len)
+{
+  return mrb_load_nstring_cxt(mrb, s, len, NULL);
+}
+
+MRB_API mrb_value
+mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *c)
+{
+  return mrb_load_nstring_cxt(mrb, s, strlen(s), c);
+}
+
+MRB_API mrb_value
+mrb_load_string(mrb_state *mrb, const char *s)
+{
+  return mrb_load_string_cxt(mrb, s, NULL);
+}
+
+#ifndef MRB_DISABLE_STDIO
+
+static void
+dump_prefix(node *tree, int offset)
+{
+  printf("%05d ", tree->lineno);
+  while (offset--) {
+    putc(' ', stdout);
+    putc(' ', stdout);
+  }
+}
+
+static void
+dump_recur(mrb_state *mrb, node *tree, int offset)
+{
+  while (tree) {
+    mrb_parser_dump(mrb, tree->car, offset);
+    tree = tree->cdr;
+  }
+}
+
+static void
+dump_args(mrb_state *mrb, node *n, int offset)
+{
+  if (n->car) {
+    dump_prefix(n, offset+1);
+    printf("mandatory args:\n");
+    dump_recur(mrb, n->car, offset+2);
+  }
+  n = n->cdr;
+  if (n->car) {
+    dump_prefix(n, offset+1);
+    printf("optional args:\n");
+    {
+      node *n2 = n->car;
+
+      while (n2) {
+        dump_prefix(n2, offset+2);
+        printf("%s=\n", mrb_sym_name(mrb, sym(n2->car->car)));
+        mrb_parser_dump(mrb, n2->car->cdr, offset+3);
+        n2 = n2->cdr;
+      }
+    }
+  }
+  n = n->cdr;
+  if (n->car) {
+    dump_prefix(n, offset+1);
+    printf("rest=*%s\n", mrb_sym_name(mrb, sym(n->car)));
+  }
+  n = n->cdr;
+  if (n->car) {
+    dump_prefix(n, offset+1);
+    printf("post mandatory args:\n");
+    dump_recur(mrb, n->car, offset+2);
+  }
+
+  n = n->cdr;
+  if (n) {
+    mrb_assert(intn(n->car) == NODE_ARGS_TAIL);
+    mrb_parser_dump(mrb, n, offset);
+  }
+}
+
+/*
+ * This function restores the GC arena on return.
+ * For this reason, if a process that further generates an object is
+ * performed at the caller, the string pointer returned as the return
+ * value may become invalid.
+ */
+static const char*
+str_dump(mrb_state *mrb, const char *str, int len)
+{
+  int ai = mrb_gc_arena_save(mrb);
+  mrb_value s;
+# if INT_MAX > MRB_INT_MAX / 4
+  /* check maximum length with "\xNN" charactor */
+  if (len > MRB_INT_MAX / 4) {
+    len = MRB_INT_MAX / 4;
+  }
+# endif
+  s = mrb_str_new(mrb, str, (mrb_int)len);
+  s = mrb_str_dump(mrb, s);
+  mrb_gc_arena_restore(mrb, ai);
+  return RSTRING_PTR(s);
+}
+#endif
+
+void
+mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
+{
+#ifndef MRB_DISABLE_STDIO
+  int nodetype;
+
+  if (!tree) return;
+  again:
+  dump_prefix(tree, offset);
+  nodetype = intn(tree->car);
+  tree = tree->cdr;
+  switch (nodetype) {
+  case NODE_BEGIN:
+    printf("NODE_BEGIN:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_RESCUE:
+    printf("NODE_RESCUE:\n");
+    if (tree->car) {
+      dump_prefix(tree, offset+1);
+      printf("body:\n");
+      mrb_parser_dump(mrb, tree->car, offset+2);
+    }
+    tree = tree->cdr;
+    if (tree->car) {
+      node *n2 = tree->car;
+
+      dump_prefix(n2, offset+1);
+      printf("rescue:\n");
+      while (n2) {
+        node *n3 = n2->car;
+        if (n3->car) {
+          dump_prefix(n2, offset+2);
+          printf("handle classes:\n");
+          dump_recur(mrb, n3->car, offset+3);
+        }
+        if (n3->cdr->car) {
+          dump_prefix(n3, offset+2);
+          printf("exc_var:\n");
+          mrb_parser_dump(mrb, n3->cdr->car, offset+3);
+        }
+        if (n3->cdr->cdr->car) {
+          dump_prefix(n3, offset+2);
+          printf("rescue body:\n");
+          mrb_parser_dump(mrb, n3->cdr->cdr->car, offset+3);
+        }
+        n2 = n2->cdr;
+      }
+    }
+    tree = tree->cdr;
+    if (tree->car) {
+      dump_prefix(tree, offset+1);
+      printf("else:\n");
+      mrb_parser_dump(mrb, tree->car, offset+2);
+    }
+    break;
+
+  case NODE_ENSURE:
+    printf("NODE_ENSURE:\n");
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    dump_prefix(tree, offset+1);
+    printf("ensure:\n");
+    mrb_parser_dump(mrb, tree->cdr->cdr, offset+2);
+    break;
+
+  case NODE_LAMBDA:
+    printf("NODE_LAMBDA:\n");
+    dump_prefix(tree, offset);
+    goto block;
+
+  case NODE_BLOCK:
+    block:
+    printf("NODE_BLOCK:\n");
+    tree = tree->cdr;
+    if (tree->car) {
+      dump_args(mrb, tree->car, offset+1);
+    }
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr->car, offset+2);
+    break;
+
+  case NODE_IF:
+    printf("NODE_IF:\n");
+    dump_prefix(tree, offset+1);
+    printf("cond:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    dump_prefix(tree, offset+1);
+    printf("then:\n");
+    mrb_parser_dump(mrb, tree->cdr->car, offset+2);
+    if (tree->cdr->cdr->car) {
+      dump_prefix(tree, offset+1);
+      printf("else:\n");
+      mrb_parser_dump(mrb, tree->cdr->cdr->car, offset+2);
+    }
+    break;
+
+  case NODE_AND:
+    printf("NODE_AND:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    mrb_parser_dump(mrb, tree->cdr, offset+1);
+    break;
+
+  case NODE_OR:
+    printf("NODE_OR:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    mrb_parser_dump(mrb, tree->cdr, offset+1);
+    break;
+
+  case NODE_CASE:
+    printf("NODE_CASE:\n");
+    if (tree->car) {
+      mrb_parser_dump(mrb, tree->car, offset+1);
+    }
+    tree = tree->cdr;
+    while (tree) {
+      dump_prefix(tree, offset+1);
+      printf("case:\n");
+      dump_recur(mrb, tree->car->car, offset+2);
+      dump_prefix(tree, offset+1);
+      printf("body:\n");
+      mrb_parser_dump(mrb, tree->car->cdr, offset+2);
+      tree = tree->cdr;
+    }
+    break;
+
+  case NODE_WHILE:
+    printf("NODE_WHILE:\n");
+    dump_prefix(tree, offset+1);
+    printf("cond:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr, offset+2);
+    break;
+
+  case NODE_UNTIL:
+    printf("NODE_UNTIL:\n");
+    dump_prefix(tree, offset+1);
+    printf("cond:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr, offset+2);
+    break;
+
+  case NODE_FOR:
+    printf("NODE_FOR:\n");
+    dump_prefix(tree, offset+1);
+    printf("var:\n");
+    {
+      node *n2 = tree->car;
+
+      if (n2->car) {
+        dump_prefix(n2, offset+2);
+        printf("pre:\n");
+        dump_recur(mrb, n2->car, offset+3);
+      }
+      n2 = n2->cdr;
+      if (n2) {
+        if (n2->car) {
+          dump_prefix(n2, offset+2);
+          printf("rest:\n");
+          mrb_parser_dump(mrb, n2->car, offset+3);
+        }
+        n2 = n2->cdr;
+        if (n2) {
+          if (n2->car) {
+            dump_prefix(n2, offset+2);
+            printf("post:\n");
+            dump_recur(mrb, n2->car, offset+3);
+          }
+        }
+      }
+    }
+    tree = tree->cdr;
+    dump_prefix(tree, offset+1);
+    printf("in:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    tree = tree->cdr;
+    dump_prefix(tree, offset+1);
+    printf("do:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    break;
+
+  case NODE_SCOPE:
+    printf("NODE_SCOPE:\n");
+    {
+      node *n2 = tree->car;
+      mrb_bool first_lval = TRUE;
+
+      if (n2 && (n2->car || n2->cdr)) {
+        dump_prefix(n2, offset+1);
+        printf("local variables:\n");
+        dump_prefix(n2, offset+2);
+        while (n2) {
+          if (n2->car) {
+            if (!first_lval) printf(", ");
+            printf("%s", mrb_sym_name(mrb, sym(n2->car)));
+            first_lval = FALSE;
+          }
+          n2 = n2->cdr;
+        }
+        printf("\n");
+      }
+    }
+    tree = tree->cdr;
+    offset++;
+    goto again;
+
+  case NODE_FCALL:
+  case NODE_CALL:
+  case NODE_SCALL:
+    switch (nodetype) {
+    case NODE_FCALL:
+      printf("NODE_FCALL:\n"); break;
+    case NODE_CALL:
+      printf("NODE_CALL(.):\n"); break;
+    case NODE_SCALL:
+      printf("NODE_SCALL(&.):\n"); break;
+    default:
+      break;
+    }
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    dump_prefix(tree, offset+1);
+    printf("method='%s' (%d)\n",
+        mrb_sym_dump(mrb, sym(tree->cdr->car)),
+        intn(tree->cdr->car));
+    tree = tree->cdr->cdr->car;
+    if (tree) {
+      dump_prefix(tree, offset+1);
+      printf("args:\n");
+      dump_recur(mrb, tree->car, offset+2);
+      if (tree->cdr) {
+        dump_prefix(tree, offset+1);
+        printf("block:\n");
+        mrb_parser_dump(mrb, tree->cdr, offset+2);
+      }
+    }
+    break;
+
+  case NODE_DOT2:
+    printf("NODE_DOT2:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    mrb_parser_dump(mrb, tree->cdr, offset+1);
+    break;
+
+  case NODE_DOT3:
+    printf("NODE_DOT3:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    mrb_parser_dump(mrb, tree->cdr, offset+1);
+    break;
+
+  case NODE_COLON2:
+    printf("NODE_COLON2:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    dump_prefix(tree, offset+1);
+    printf("::%s\n", mrb_sym_name(mrb, sym(tree->cdr)));
+    break;
+
+  case NODE_COLON3:
+    printf("NODE_COLON3: ::%s\n", mrb_sym_name(mrb, sym(tree)));
+    break;
+
+  case NODE_ARRAY:
+    printf("NODE_ARRAY:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_HASH:
+    printf("NODE_HASH:\n");
+    while (tree) {
+      dump_prefix(tree, offset+1);
+      printf("key:\n");
+      mrb_parser_dump(mrb, tree->car->car, offset+2);
+      dump_prefix(tree, offset+1);
+      printf("value:\n");
+      mrb_parser_dump(mrb, tree->car->cdr, offset+2);
+      tree = tree->cdr;
+    }
+    break;
+
+  case NODE_KW_HASH:
+    printf("NODE_KW_HASH:\n");
+    while (tree) {
+      dump_prefix(tree, offset+1);
+      printf("key:\n");
+      mrb_parser_dump(mrb, tree->car->car, offset+2);
+      dump_prefix(tree, offset+1);
+      printf("value:\n");
+      mrb_parser_dump(mrb, tree->car->cdr, offset+2);
+      tree = tree->cdr;
+    }
+    break;
+
+  case NODE_SPLAT:
+    printf("NODE_SPLAT:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_ASGN:
+    printf("NODE_ASGN:\n");
+    dump_prefix(tree, offset+1);
+    printf("lhs:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    dump_prefix(tree, offset+1);
+    printf("rhs:\n");
+    mrb_parser_dump(mrb, tree->cdr, offset+2);
+    break;
+
+  case NODE_MASGN:
+    printf("NODE_MASGN:\n");
+    dump_prefix(tree, offset+1);
+    printf("mlhs:\n");
+    {
+      node *n2 = tree->car;
+
+      if (n2->car) {
+        dump_prefix(tree, offset+2);
+        printf("pre:\n");
+        dump_recur(mrb, n2->car, offset+3);
+      }
+      n2 = n2->cdr;
+      if (n2) {
+        if (n2->car) {
+          dump_prefix(n2, offset+2);
+          printf("rest:\n");
+          if (n2->car == (node*)-1) {
+            dump_prefix(n2, offset+2);
+            printf("(empty)\n");
+          }
+          else {
+            mrb_parser_dump(mrb, n2->car, offset+3);
+          }
+        }
+        n2 = n2->cdr;
+        if (n2) {
+          if (n2->car) {
+            dump_prefix(n2, offset+2);
+            printf("post:\n");
+            dump_recur(mrb, n2->car, offset+3);
+          }
+        }
+      }
+    }
+    dump_prefix(tree, offset+1);
+    printf("rhs:\n");
+    mrb_parser_dump(mrb, tree->cdr, offset+2);
+    break;
+
+  case NODE_OP_ASGN:
+    printf("NODE_OP_ASGN:\n");
+    dump_prefix(tree, offset+1);
+    printf("lhs:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    tree = tree->cdr;
+    dump_prefix(tree, offset+1);
+    printf("op='%s' (%d)\n", mrb_sym_name(mrb, sym(tree->car)), intn(tree->car));
+    tree = tree->cdr;
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    break;
+
+  case NODE_SUPER:
+    printf("NODE_SUPER:\n");
+    if (tree) {
+      dump_prefix(tree, offset+1);
+      printf("args:\n");
+      dump_recur(mrb, tree->car, offset+2);
+      if (tree->cdr) {
+        dump_prefix(tree, offset+1);
+        printf("block:\n");
+        mrb_parser_dump(mrb, tree->cdr, offset+2);
+      }
+    }
+    break;
+
+  case NODE_ZSUPER:
+    printf("NODE_ZSUPER\n");
+    break;
+
+  case NODE_RETURN:
+    printf("NODE_RETURN:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_YIELD:
+    printf("NODE_YIELD:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_BREAK:
+    printf("NODE_BREAK:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_NEXT:
+    printf("NODE_NEXT:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_REDO:
+    printf("NODE_REDO\n");
+    break;
+
+  case NODE_RETRY:
+    printf("NODE_RETRY\n");
+    break;
+
+  case NODE_LVAR:
+    printf("NODE_LVAR %s\n", mrb_sym_name(mrb, sym(tree)));
+    break;
+
+  case NODE_GVAR:
+    printf("NODE_GVAR %s\n", mrb_sym_name(mrb, sym(tree)));
+    break;
+
+  case NODE_IVAR:
+    printf("NODE_IVAR %s\n", mrb_sym_name(mrb, sym(tree)));
+    break;
+
+  case NODE_CVAR:
+    printf("NODE_CVAR %s\n", mrb_sym_name(mrb, sym(tree)));
+    break;
+
+  case NODE_NVAR:
+    printf("NODE_NVAR %d\n", intn(tree));
+    break;
+
+  case NODE_CONST:
+    printf("NODE_CONST %s\n", mrb_sym_name(mrb, sym(tree)));
+    break;
+
+  case NODE_MATCH:
+    printf("NODE_MATCH:\n");
+    dump_prefix(tree, offset + 1);
+    printf("lhs:\n");
+    mrb_parser_dump(mrb, tree->car, offset + 2);
+    dump_prefix(tree, offset + 1);
+    printf("rhs:\n");
+    mrb_parser_dump(mrb, tree->cdr, offset + 2);
+    break;
+
+  case NODE_BACK_REF:
+    printf("NODE_BACK_REF: $%c\n", intn(tree));
+    break;
+
+  case NODE_NTH_REF:
+    printf("NODE_NTH_REF: $%d\n", intn(tree));
+    break;
+
+  case NODE_ARG:
+    printf("NODE_ARG %s\n", mrb_sym_name(mrb, sym(tree)));
+    break;
+
+  case NODE_BLOCK_ARG:
+    printf("NODE_BLOCK_ARG:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_INT:
+    printf("NODE_INT %s base %d\n", (char*)tree->car, intn(tree->cdr->car));
+    break;
+
+  case NODE_FLOAT:
+    printf("NODE_FLOAT %s\n", (char*)tree);
+    break;
+
+  case NODE_NEGATE:
+    printf("NODE_NEGATE:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_STR:
+    printf("NODE_STR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr));
+    break;
+
+  case NODE_DSTR:
+    printf("NODE_DSTR:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_XSTR:
+    printf("NODE_XSTR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr));
+    break;
+
+  case NODE_DXSTR:
+    printf("NODE_DXSTR:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_REGX:
+    printf("NODE_REGX /%s/%s\n", (char*)tree->car, (char*)tree->cdr);
+    break;
+
+  case NODE_DREGX:
+    printf("NODE_DREGX:\n");
+    dump_recur(mrb, tree->car, offset+1);
+    dump_prefix(tree, offset);
+    printf("tail: %s\n", (char*)tree->cdr->cdr->car);
+    if (tree->cdr->cdr->cdr->car) {
+      dump_prefix(tree, offset);
+      printf("opt: %s\n", (char*)tree->cdr->cdr->cdr->car);
+    }
+    if (tree->cdr->cdr->cdr->cdr) {
+      dump_prefix(tree, offset);
+      printf("enc: %s\n", (char*)tree->cdr->cdr->cdr->cdr);
+    }
+    break;
+
+  case NODE_SYM:
+    printf("NODE_SYM :%s (%d)\n", mrb_sym_dump(mrb, sym(tree)),
+           intn(tree));
+    break;
+
+  case NODE_DSYM:
+    printf("NODE_DSYM:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_WORDS:
+    printf("NODE_WORDS:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_SYMBOLS:
+    printf("NODE_SYMBOLS:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_LITERAL_DELIM:
+    printf("NODE_LITERAL_DELIM\n");
+    break;
+
+  case NODE_SELF:
+    printf("NODE_SELF\n");
+    break;
+
+  case NODE_NIL:
+    printf("NODE_NIL\n");
+    break;
+
+  case NODE_TRUE:
+    printf("NODE_TRUE\n");
+    break;
+
+  case NODE_FALSE:
+    printf("NODE_FALSE\n");
+    break;
+
+  case NODE_ALIAS:
+    printf("NODE_ALIAS %s %s:\n",
+        mrb_sym_dump(mrb, sym(tree->car)),
+        mrb_sym_dump(mrb, sym(tree->cdr)));
+    break;
+
+  case NODE_UNDEF:
+    printf("NODE_UNDEF");
+    {
+      node *t = tree;
+      while (t) {
+        printf(" %s", mrb_sym_dump(mrb, sym(t->car)));
+        t = t->cdr;
+      }
+    }
+    printf(":\n");
+    break;
+
+  case NODE_CLASS:
+    printf("NODE_CLASS:\n");
+    if (tree->car->car == (node*)0) {
+      dump_prefix(tree, offset+1);
+      printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
+    }
+    else if (tree->car->car == (node*)1) {
+      dump_prefix(tree, offset+1);
+      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
+    }
+    else {
+      mrb_parser_dump(mrb, tree->car->car, offset+1);
+      dump_prefix(tree, offset+1);
+      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
+    }
+    if (tree->cdr->car) {
+      dump_prefix(tree, offset+1);
+      printf("super:\n");
+      mrb_parser_dump(mrb, tree->cdr->car, offset+2);
+    }
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr->cdr->car->cdr, offset+2);
+    break;
+
+  case NODE_MODULE:
+    printf("NODE_MODULE:\n");
+    if (tree->car->car == (node*)0) {
+      dump_prefix(tree, offset+1);
+      printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
+    }
+    else if (tree->car->car == (node*)1) {
+      dump_prefix(tree, offset+1);
+      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
+    }
+    else {
+      mrb_parser_dump(mrb, tree->car->car, offset+1);
+      dump_prefix(tree, offset+1);
+      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
+    }
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2);
+    break;
+
+  case NODE_SCLASS:
+    printf("NODE_SCLASS:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2);
+    break;
+
+  case NODE_DEF:
+    printf("NODE_DEF:\n");
+    dump_prefix(tree, offset+1);
+    printf("%s\n", mrb_sym_dump(mrb, sym(tree->car)));
+    tree = tree->cdr;
+    {
+      node *n2 = tree->car;
+      mrb_bool first_lval = TRUE;
+
+      if (n2 && (n2->car || n2->cdr)) {
+        dump_prefix(n2, offset+1);
+        printf("local variables:\n");
+        dump_prefix(n2, offset+2);
+        while (n2) {
+          if (n2->car) {
+            if (!first_lval) printf(", ");
+            printf("%s", mrb_sym_name(mrb, sym(n2->car)));
+            first_lval = FALSE;
+          }
+          n2 = n2->cdr;
+        }
+        printf("\n");
+      }
+    }
+    tree = tree->cdr;
+    if (tree->car) {
+      dump_args(mrb, tree->car, offset);
+    }
+    mrb_parser_dump(mrb, tree->cdr->car, offset+1);
+    break;
+
+  case NODE_SDEF:
+    printf("NODE_SDEF:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    tree = tree->cdr;
+    dump_prefix(tree, offset+1);
+    printf(":%s\n", mrb_sym_dump(mrb, sym(tree->car)));
+    tree = tree->cdr->cdr;
+    if (tree->car) {
+      dump_args(mrb, tree->car, offset+1);
+    }
+    tree = tree->cdr;
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    break;
+
+  case NODE_POSTEXE:
+    printf("NODE_POSTEXE:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_HEREDOC:
+    printf("NODE_HEREDOC (<<%s):\n", ((parser_heredoc_info*)tree)->term);
+    dump_recur(mrb, ((parser_heredoc_info*)tree)->doc, offset+1);
+    break;
+
+  case NODE_ARGS_TAIL:
+    printf("NODE_ARGS_TAIL:\n");
+    {
+      node *kws = tree->car;
+
+      while (kws) {
+        mrb_parser_dump(mrb, kws->car, offset+1);
+        kws = kws->cdr;
+      }
+    }
+    tree = tree->cdr;
+    if (tree->car) {
+      mrb_assert(intn(tree->car->car) == NODE_KW_REST_ARGS);
+      mrb_parser_dump(mrb, tree->car, offset+1);
+    }
+    tree = tree->cdr;
+    if (tree->car) {
+      dump_prefix(tree, offset+1);
+      printf("block='%s'\n", mrb_sym_name(mrb, sym(tree->car)));
+    }
+    break;
+
+  case NODE_KW_ARG:
+    printf("NODE_KW_ARG %s:\n", mrb_sym_name(mrb, sym(tree->car)));
+    mrb_parser_dump(mrb, tree->cdr->car, offset + 1);
+    break;
+
+  case NODE_KW_REST_ARGS:
+    printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree)));
+    break;
+
+  default:
+    printf("node type: %d (0x%x)\n", nodetype, (unsigned)nodetype);
+    break;
+  }
+#endif
+}
index fa191e6..b25bdaf 100644 (file)
@@ -3,35 +3,33 @@ MRuby::Gem::Specification.new 'mruby-compiler' do |spec|
   spec.author  = 'mruby developers'
   spec.summary = 'mruby compiler library'
 
-  current_dir = spec.dir
-  current_build_dir = spec.build_dir
-
-  lex_def = "#{current_dir}/core/lex.def"
-  core_objs = Dir.glob("#{current_dir}/core/*.c").map { |f|
+  lex_def = "#{dir}/core/lex.def"
+  core_objs = Dir.glob("#{dir}/core/*.c").map { |f|
     next nil if build.cxx_exception_enabled? and f =~ /(codegen).c$/
-    objfile(f.pathmap("#{current_build_dir}/core/%n"))
+    objfile(f.pathmap("#{build_dir}/core/%n"))
   }.compact
 
   if build.cxx_exception_enabled?
     core_objs <<
-      build.compile_as_cxx("#{current_build_dir}/core/y.tab.c", "#{current_build_dir}/core/y.tab.cxx",
-                           objfile("#{current_build_dir}/y.tab"), ["#{current_dir}/core"]) <<
-      build.compile_as_cxx("#{current_dir}/core/codegen.c", "#{current_build_dir}/core/codegen.cxx")
+      build.compile_as_cxx("#{dir}/core/y.tab.c", "#{build_dir}/core/y.tab.cxx",
+                           objfile("#{build_dir}/y.tab"), ["#{dir}/core"]) <<
+      build.compile_as_cxx("#{dir}/core/codegen.c", "#{build_dir}/core/codegen.cxx")
   else
-    core_objs << objfile("#{current_build_dir}/core/y.tab")
-    file objfile("#{current_build_dir}/core/y.tab") => "#{current_build_dir}/core/y.tab.c" do |t|
-      cc.run t.name, t.prerequisites.first, [], ["#{current_dir}/core"]
+    core_objs << objfile("#{build_dir}/core/y.tab")
+    file objfile("#{build_dir}/core/y.tab") => "#{dir}/core/y.tab.c" do |t|
+      cc.run t.name, t.prerequisites.first, [], ["#{dir}/core"]
     end
   end
 
   # Parser
-  file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y", lex_def] do |t|
-    FileUtils.mkdir_p File.dirname t.name
+  file "#{dir}/core/y.tab.c" => ["#{dir}/core/parse.y", lex_def] do |t|
     yacc.run t.name, t.prerequisites.first
+    content = File.read(t.name).gsub(/^#line +\d+ +"\K.*$/){$&.relative_path}
+    File.write(t.name, content)
   end
 
   # Lexical analyzer
-  file lex_def => "#{current_dir}/core/keywords" do |t|
+  file lex_def => "#{dir}/core/keywords" do |t|
     gperf.run t.name, t.prerequisites.first
   end
 
diff --git a/third-party/mruby/mrbgems/mruby-complex/mrbgem.rake b/third-party/mruby/mrbgems/mruby-complex/mrbgem.rake
new file mode 100644 (file)
index 0000000..8f782ae
--- /dev/null
@@ -0,0 +1,7 @@
+MRuby::Gem::Specification.new('mruby-complex') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Complex class'
+
+  spec.add_dependency 'mruby-math', core: 'mruby-math'
+end
diff --git a/third-party/mruby/mrbgems/mruby-complex/mrblib/complex.rb b/third-party/mruby/mrbgems/mruby-complex/mrblib/complex.rb
new file mode 100644 (file)
index 0000000..74c128a
--- /dev/null
@@ -0,0 +1,122 @@
+class Complex < Numeric
+  def self.polar(abs, arg = 0)
+    Complex(abs * Math.cos(arg), abs * Math.sin(arg))
+  end
+
+  def inspect
+    "(#{to_s})"
+  end
+
+  def to_s
+    "#{real}#{'+' unless imaginary < 0}#{imaginary}i"
+  end
+
+  def +@
+    Complex(real, imaginary)
+  end
+
+  def -@
+    Complex(-real, -imaginary)
+  end
+
+  def +(rhs)
+    if rhs.is_a? Complex
+      Complex(real + rhs.real, imaginary + rhs.imaginary)
+    elsif rhs.is_a? Numeric
+      Complex(real + rhs, imaginary)
+    end
+  end
+
+  def -(rhs)
+    if rhs.is_a? Complex
+      Complex(real - rhs.real, imaginary - rhs.imaginary)
+    elsif rhs.is_a? Numeric
+      Complex(real - rhs, imaginary)
+    end
+  end
+
+  def *(rhs)
+    if rhs.is_a? Complex
+      Complex(real * rhs.real - imaginary * rhs.imaginary, real * rhs.imaginary + rhs.real * imaginary)
+    elsif rhs.is_a? Numeric
+      Complex(real * rhs, imaginary * rhs)
+    end
+  end
+
+  def /(rhs)
+    if rhs.is_a? Complex
+      __div__(rhs)
+    elsif rhs.is_a? Numeric
+      Complex(real / rhs, imaginary / rhs)
+    end
+  end
+  alias_method :quo, :/
+
+  def ==(rhs)
+    if rhs.is_a? Complex
+      real == rhs.real && imaginary == rhs.imaginary
+    elsif rhs.is_a? Numeric
+      imaginary == 0 && real == rhs
+    end
+  end
+
+  def abs
+    Math.hypot imaginary, real
+  end
+  alias_method :magnitude, :abs
+
+  def abs2
+    real * real + imaginary * imaginary
+  end
+
+  def arg
+    Math.atan2 imaginary, real
+  end
+  alias_method :angle, :arg
+  alias_method :phase, :arg
+
+  def conjugate
+    Complex(real, -imaginary)
+  end
+  alias_method :conj, :conjugate
+
+  def fdiv(numeric)
+    Complex(real.to_f / numeric, imaginary.to_f / numeric)
+  end
+
+  def polar
+    [abs, arg]
+  end
+
+  def real?
+    false
+  end
+
+  def rectangular
+    [real, imaginary]
+  end
+  alias_method :rect, :rectangular
+
+  def to_r
+    raise RangeError.new "can't convert #{to_s} into Rational" unless imaginary.zero?
+    Rational(real, 1)
+  end
+
+  alias_method :imag, :imaginary
+
+  [Fixnum, Float].each do |cls|
+    [:+, :-, :*, :/, :==].each do |op|
+      cls.instance_eval do
+        original_operator_name = :"__original_operator_#{op}_complex"
+        alias_method original_operator_name, op
+        define_method op do |rhs|
+          if rhs.is_a? Complex
+            Complex(self).__send__(op, rhs)
+          else
+            __send__(original_operator_name, rhs)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/third-party/mruby/mrbgems/mruby-complex/src/complex.c b/third-party/mruby/mrbgems/mruby-complex/src/complex.c
new file mode 100644 (file)
index 0000000..0432da6
--- /dev/null
@@ -0,0 +1,248 @@
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/numeric.h>
+#include <math.h>
+
+#ifdef MRB_WITHOUT_FLOAT
+# error Complex conflicts 'MRB_WITHOUT_FLOAT' configuration in your 'build_config.rb'
+#endif
+
+struct mrb_complex {
+  mrb_float real;
+  mrb_float imaginary;
+};
+
+#ifdef MRB_USE_FLOAT
+#define F(x) x##f
+#else
+#define F(x) x
+#endif
+
+#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT)
+
+#define COMPLEX_USE_ISTRUCT
+/* use TT_ISTRUCT */
+#include <mruby/istruct.h>
+
+#define complex_ptr(mrb, v) (struct mrb_complex*)mrb_istruct_ptr(v)
+
+static struct RBasic*
+complex_alloc(mrb_state *mrb, struct RClass *c, struct mrb_complex **p)
+{
+  struct RIStruct *s;
+
+  s = (struct RIStruct*)mrb_obj_alloc(mrb, MRB_TT_ISTRUCT, c);
+  *p = (struct mrb_complex*)s->inline_data;
+
+  return (struct RBasic*)s;
+}
+
+#else
+/* use TT_DATA */
+#include <mruby/data.h>
+
+static const struct mrb_data_type mrb_complex_type = {"Complex", mrb_free};
+
+static struct RBasic*
+complex_alloc(mrb_state *mrb, struct RClass *c, struct mrb_complex **p)
+{
+  struct RData *d;
+
+  Data_Make_Struct(mrb, c, struct mrb_complex, &mrb_complex_type, *p, d);
+
+  return (struct RBasic*)d;
+}
+
+static struct mrb_complex*
+complex_ptr(mrb_state *mrb, mrb_value v)
+{
+  struct mrb_complex *p;
+
+  p = DATA_GET_PTR(mrb, v, &mrb_complex_type, struct mrb_complex);
+  if (!p) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized complex");
+  }
+  return p;
+}
+#endif
+
+static mrb_value
+complex_new(mrb_state *mrb, mrb_float real, mrb_float imaginary)
+{
+  struct RClass *c = mrb_class_get(mrb, "Complex");
+  struct mrb_complex *p;
+  struct RBasic *comp = complex_alloc(mrb, c, &p);
+  p->real = real;
+  p->imaginary = imaginary;
+  MRB_SET_FROZEN_FLAG(comp);
+
+  return mrb_obj_value(comp);
+}
+
+static mrb_value
+complex_real(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_complex *p = complex_ptr(mrb, self);
+  return mrb_float_value(mrb, p->real);
+}
+
+static mrb_value
+complex_imaginary(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_complex *p = complex_ptr(mrb, self);
+  return mrb_float_value(mrb, p->imaginary);
+}
+
+static mrb_value
+complex_s_rect(mrb_state *mrb, mrb_value self)
+{
+  mrb_float real, imaginary = 0.0;
+
+  mrb_get_args(mrb, "f|f", &real, &imaginary);
+  return complex_new(mrb, real, imaginary);
+}
+
+static mrb_value
+complex_to_f(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_complex *p = complex_ptr(mrb, self);
+
+  if (p->imaginary != 0) {
+    mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %v into Float", self);
+  }
+
+  return mrb_float_value(mrb, p->real);
+}
+
+static mrb_value
+complex_to_i(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_complex *p = complex_ptr(mrb, self);
+
+  if (p->imaginary != 0) {
+    mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %v into Float", self);
+  }
+  return mrb_int_value(mrb, p->real);
+}
+
+static mrb_value
+complex_to_c(mrb_state *mrb, mrb_value self)
+{
+  return self;
+}
+
+/* Arithmetic on (significand, exponent) pairs avoids premature overflow in
+   complex division */
+struct float_pair {
+  mrb_float s;
+  int x;
+};
+
+static void
+add_pair(struct float_pair *s, struct float_pair const *a,
+         struct float_pair const *b)
+{
+  if (b->s == 0.0F) {
+    *s = *a;
+  } else if (a->s == 0.0F) {
+    *s = *b;
+  } else if (a->x >= b->x) {
+    s->s = a->s + F(ldexp)(b->s, b->x - a->x);
+    s->x = a->x;
+  } else {
+    s->s = F(ldexp)(a->s, a->x - b->x) + b->s;
+    s->x = b->x;
+  }
+}
+
+static void
+mul_pair(struct float_pair *p, struct float_pair const *a,
+         struct float_pair const *b)
+{
+  p->s = a->s * b->s;
+  p->x = a->x + b->x;
+}
+
+static void
+div_pair(struct float_pair *q, struct float_pair const *a,
+         struct float_pair const *b)
+{
+  q->s = a->s / b->s;
+  q->x = a->x - b->x;
+}
+
+static mrb_value
+complex_div(mrb_state *mrb, mrb_value self)
+{
+  mrb_value rhs = mrb_get_arg1(mrb);
+  struct mrb_complex *a, *b;
+  struct float_pair ar, ai, br, bi;
+  struct float_pair br2, bi2;
+  struct float_pair div;
+  struct float_pair ar_br, ai_bi;
+  struct float_pair ai_br, ar_bi;
+  struct float_pair zr, zi;
+
+  a = complex_ptr(mrb, self);
+  b = complex_ptr(mrb, rhs);
+
+  /* Split floating point components into significand and exponent */
+  ar.s = F(frexp)(a->real, &ar.x);
+  ai.s = F(frexp)(a->imaginary, &ai.x);
+  br.s = F(frexp)(b->real, &br.x);
+  bi.s = F(frexp)(b->imaginary, &bi.x);
+
+  /* Perform arithmetic on (significand, exponent) pairs to produce
+     the result: */
+
+  /* the divisor */
+  mul_pair(&br2, &br, &br);
+  mul_pair(&bi2, &bi, &bi);
+  add_pair(&div, &br2, &bi2);
+
+  /* real component */
+  mul_pair(&ar_br, &ar, &br);
+  mul_pair(&ai_bi, &ai, &bi);
+  add_pair(&zr, &ar_br, &ai_bi);
+  div_pair(&zr, &zr, &div);
+
+  /* imaginary component */
+  mul_pair(&ai_br, &ai, &br);
+  mul_pair(&ar_bi, &ar, &bi);
+  ar_bi.s = -ar_bi.s;
+  add_pair(&zi, &ai_br, &ar_bi);
+  div_pair(&zi, &zi, &div);
+
+  /* assemble the result */
+  return complex_new(mrb, F(ldexp)(zr.s, zr.x), F(ldexp)(zi.s, zi.x));
+}
+
+void mrb_mruby_complex_gem_init(mrb_state *mrb)
+{
+  struct RClass *comp;
+
+#ifdef COMPLEX_USE_ISTRUCT
+  mrb_assert(sizeof(struct mrb_complex) < ISTRUCT_DATA_SIZE);
+#endif
+  comp = mrb_define_class(mrb, "Complex", mrb_class_get(mrb, "Numeric"));
+#ifdef COMPLEX_USE_ISTRUCT
+  MRB_SET_INSTANCE_TT(comp, MRB_TT_ISTRUCT);
+#else
+  MRB_SET_INSTANCE_TT(comp, MRB_TT_DATA);
+#endif
+  mrb_undef_class_method(mrb, comp, "new");
+  mrb_define_class_method(mrb, comp, "rectangular", complex_s_rect, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
+  mrb_define_class_method(mrb, comp, "rect", complex_s_rect, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, mrb->kernel_module, "Complex", complex_s_rect, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, comp, "real", complex_real, MRB_ARGS_NONE());
+  mrb_define_method(mrb, comp, "imaginary", complex_imaginary, MRB_ARGS_NONE());
+  mrb_define_method(mrb, comp, "to_f", complex_to_f, MRB_ARGS_NONE());
+  mrb_define_method(mrb, comp, "to_i", complex_to_i, MRB_ARGS_NONE());
+  mrb_define_method(mrb, comp, "to_c", complex_to_c, MRB_ARGS_NONE());
+  mrb_define_method(mrb, comp, "__div__", complex_div, MRB_ARGS_REQ(1));
+}
+
+void
+mrb_mruby_complex_gem_final(mrb_state* mrb)
+{
+}
diff --git a/third-party/mruby/mrbgems/mruby-complex/test/complex.rb b/third-party/mruby/mrbgems/mruby-complex/test/complex.rb
new file mode 100644 (file)
index 0000000..d996e82
--- /dev/null
@@ -0,0 +1,153 @@
+def assert_complex(real, exp)
+  assert "assert_complex" do
+    assert_float real.real,      exp.real
+    assert_float real.imaginary, exp.imaginary
+  end
+end
+
+assert 'Complex' do
+  c = 123i
+  assert_equal Complex, c.class
+  assert_equal [c.real, c.imaginary], [0, 123]
+  c = 123 + -1.23i
+  assert_equal Complex, c.class
+  assert_equal [c.real, c.imaginary], [123, -1.23]
+end
+
+assert 'Complex::polar' do
+  assert_complex Complex.polar(3, 0),           (3  +  0i)
+  assert_complex Complex.polar(3, Math::PI/2),  (0  +  3i)
+  assert_complex Complex.polar(3, Math::PI),    (-3 +  0i)
+  assert_complex Complex.polar(3, -Math::PI/2), (0  + -3i)
+end
+
+assert 'Complex::rectangular' do
+  assert_complex Complex.rectangular(1, 2), (1 + 2i)
+end
+
+assert 'Complex#*' do
+  assert_complex Complex(2, 3)  * Complex(2, 3),  (-5    + 12i)
+  assert_complex Complex(900)   * Complex(1),     (900   + 0i)
+  assert_complex Complex(-2, 9) * Complex(-9, 2), (0     - 85i)
+  assert_complex Complex(9, 8)  * 4,              (36    + 32i)
+  assert_complex Complex(20, 9) * 9.8,            (196.0 + 88.2i)
+end
+
+assert 'Complex#+' do
+  assert_complex Complex(2, 3)  + Complex(2, 3) , (4    + 6i)
+  assert_complex Complex(900)   + Complex(1)    , (901  + 0i)
+  assert_complex Complex(-2, 9) + Complex(-9, 2), (-11  + 11i)
+  assert_complex Complex(9, 8)  + 4             , (13   + 8i)
+  assert_complex Complex(20, 9) + 9.8           , (29.8 + 9i)
+end
+
+assert 'Complex#-' do
+  assert_complex Complex(2, 3)  - Complex(2, 3) , (0    + 0i)
+  assert_complex Complex(900)   - Complex(1)    , (899  + 0i)
+  assert_complex Complex(-2, 9) - Complex(-9, 2), (7    + 7i)
+  assert_complex Complex(9, 8)  - 4             , (5    + 8i)
+  assert_complex Complex(20, 9) - 9.8           , (10.2 + 9i)
+end
+
+assert 'Complex#-@' do
+  assert_complex(-Complex(1, 2), (-1 - 2i))
+end
+
+assert 'Complex#/' do
+  assert_complex Complex(2, 3)  / Complex(2, 3) , (1                  + 0i)
+  assert_complex Complex(900)   / Complex(1)    , (900                + 0i)
+  assert_complex Complex(-2, 9) / Complex(-9, 2), ((36 / 85)          - (77i / 85))
+  assert_complex Complex(9, 8)  / 4             , ((9 / 4)            + 2i)
+  assert_complex Complex(20, 9) / 9.8           , (2.0408163265306123 + 0.9183673469387754i)
+  if 1e39.infinite? then
+    # MRB_USE_FLOAT in effect
+    ten = 1e21
+    one = 1e20
+  else
+    ten = 1e201
+    one = 1e200
+  end
+  assert_complex Complex(ten, ten) / Complex(one, one), Complex(10.0, 0.0)
+end
+
+assert 'Complex#==' do
+  assert_true  Complex(2, 3)  == Complex(2, 3)
+  assert_true  Complex(5)     == 5
+  assert_true  Complex(0)     == 0.0
+end
+
+assert 'Complex#abs' do
+  assert_float Complex(-1).abs,        1
+  assert_float Complex(3.0, -4.0).abs, 5.0
+  if 1e39.infinite? then
+    # MRB_USE_FLOAT in effect
+    exp = 125
+  else
+    exp = 1021
+  end
+  assert_true Complex(3.0*2.0**exp, 4.0*2.0**exp).abs.finite?
+  assert_float Complex(3.0*2.0**exp, 4.0*2.0**exp).abs, 5.0*2.0**exp
+end
+
+assert 'Complex#abs2' do
+  assert_float Complex(-1).abs2,        1
+  assert_float Complex(3.0, -4.0).abs2, 25.0
+end
+
+assert 'Complex#arg' do
+  assert_float Complex.polar(3, Math::PI/2).arg, 1.5707963267948966
+end
+
+assert 'Complex#conjugate' do
+  assert_complex Complex(1, 2).conjugate, (1 - 2i)
+end
+
+assert 'Complex#fdiv' do
+  assert_complex Complex(11, 22).fdiv(3), (3.6666666666666665 + 7.333333333333333i)
+end
+
+assert 'Complex#imaginary' do
+  assert_float Complex(7).imaginary    , 0
+  assert_float Complex(9, -4).imaginary, -4
+end
+
+assert 'Complex#polar' do
+  assert_equal Complex(1, 2).polar, [2.23606797749979, 1.1071487177940904]
+end
+
+assert 'Complex#real' do
+  assert_float Complex(7).real,     7
+  assert_float Complex(9, -4).real, 9
+end
+
+assert 'Complex#real?' do
+  assert_false Complex(1).real?
+end
+
+assert 'Complex::rectangular' do
+  assert_equal Complex(1, 2).rectangular, [1, 2]
+end
+
+assert 'Complex::to_c' do
+  assert_equal Complex(1, 2).to_c, Complex(1, 2)
+end
+
+assert 'Complex::to_f' do
+  assert_float Complex(1, 0).to_f, 1.0
+  assert_raise(RangeError) do
+    Complex(1, 2).to_f
+  end
+end
+
+assert 'Complex::to_i' do
+  assert_equal Complex(1, 0).to_i, 1
+  assert_raise(RangeError) do
+    Complex(1, 2).to_i
+  end
+end
+
+assert 'Complex#frozen?' do
+  assert_predicate(1i, :frozen?)
+  assert_predicate(Complex(2,3), :frozen?)
+  assert_predicate(4+5i, :frozen?)
+end
index 98515ea..43d0926 100644 (file)
@@ -6,28 +6,30 @@ module Enumerable
   def chain(*args)
     Enumerator::Chain.new(self, *args)
   end
+end
 
+class Enumerator
   def +(other)
-    Enumerator::Chain.new(self, other)
+    Chain.new(self, other)
   end
-end
 
-class Enumerator
   class Chain
     include Enumerable
 
     def initialize(*args)
-      @enums = args
-    end
-
-    def initialize_copy(orig)
-      @enums = orig.__copy_enums
+      @enums = args.freeze
+      @pos = -1
     end
 
     def each(&block)
-      return to_enum unless block_given?
+      return to_enum unless block
 
-      @enums.each { |e| e.each(&block) }
+      i = 0
+      while i < @enums.size
+        @pos = i
+        @enums[i].each(&block)
+        i += 1
+      end
 
       self
     end
@@ -40,21 +42,21 @@ class Enumerator
     end
 
     def rewind
-      @enums.reverse_each do |e|
+      while 0 <= @pos && @pos < @enums.size
+        e = @enums[@pos]
         e.rewind if e.respond_to?(:rewind)
+        @pos -= 1
       end
 
       self
     end
 
-    def inspect
-      "#<#{self.class}: #{@enums.inspect}>"
+    def +(other)
+      self.class.new(self, other)
     end
 
-    def __copy_enums
-      @enums.each_with_object([]) do |e, a|
-        a << e.clone
-      end
+    def inspect
+      "#<#{self.class}: #{@enums.inspect}>"
     end
   end
 end
index 4dd59bd..45bbc9a 100644 (file)
@@ -12,9 +12,9 @@ assert("Enumerable#chain") do
   assert_raise(NoMethodError) { c.chain }
 end
 
-assert("Enumerable#+") do
+assert("Enumerator#+") do
   a = [].each
-  b = {}.reverse_each
+  b = {}.each
   c = Object.new # not has #each method
 
   assert_kind_of Enumerator::Chain, a + b
@@ -24,7 +24,7 @@ assert("Enumerable#+") do
   assert_raise(NoMethodError) { c + a }
 end
 
-assert("Enumerator.new") do
+assert("Enumerator::Chain.new") do
   a = []
   b = {}
   c = Object.new # not has #each method
@@ -46,13 +46,13 @@ assert("Enumerator::Chain#each") do
   assert_kind_of Enumerator, aa.each
   assert_equal [1, 2, 3, 1, 2, 3], aa.each.to_a
 
-  aa = a.chain(a.reverse_each)
+  aa = a.chain(6..9)
   assert_kind_of Enumerator, aa.each
-  assert_equal [1, 2, 3, 3, 2, 1], aa.each.to_a
+  assert_equal [1, 2, 3, 6, 7, 8, 9], aa.each.to_a
 
-  aa = a.chain(a.reverse_each, a)
+  aa = a.chain((-3..-2).each_with_index, a)
   assert_kind_of Enumerator, aa.each
-  assert_equal [1, 2, 3, 3, 2, 1, 1, 2, 3], aa.each.to_a
+  assert_equal [1, 2, 3, [-3, 0], [-2, 1], 1, 2, 3], aa.each.to_a
 
   aa = a.chain(Object.new)
   assert_kind_of Enumerator, aa.each
@@ -65,12 +65,44 @@ assert("Enumerator::Chain#size") do
   aa = a.chain(a)
   assert_equal 6, aa.size
 
-  aa = a.chain(a.reverse_each)
+  aa = a.chain(3..4)
   assert_nil aa.size
 
-  aa = a.chain(a.reverse_each, a)
+  aa = a.chain(3..4, a)
   assert_nil aa.size
 
   aa = a.chain(Object.new)
   assert_nil aa.size
 end
+
+assert("Enumerator::Chain#rewind") do
+  rewound = nil
+  e1 = [1, 2]
+  e2 = (4..6)
+  (class << e1; self end).define_method(:rewind) { rewound << self }
+  (class << e2; self end).define_method(:rewind) { rewound << self }
+  c = e1.chain(e2)
+
+  rewound = []
+  c.rewind
+  assert_equal [], rewound
+
+  rewound = []
+  c.each{break c}.rewind
+  assert_equal [e1], rewound
+
+  rewound = []
+  c.each{}.rewind
+  assert_equal [e2, e1], rewound
+end
+
+assert("Enumerator::Chain#+") do
+  a = [].chain
+  b = {}.chain
+  c = Object.new # not has #each method
+
+  assert_kind_of Enumerator::Chain, a + b
+  assert_kind_of Enumerator::Chain, a + c
+  assert_kind_of Enumerator::Chain, b + a
+  assert_kind_of Enumerator::Chain, b + c
+end
index 99b9cdd..f155119 100644 (file)
@@ -811,10 +811,6 @@ module Enumerable
     h
   end
 
-  def nil.to_h
-    {}
-  end
-
   def uniq(&block)
     hash = {}
     if block
@@ -830,4 +826,34 @@ module Enumerable
     end
     hash.values
   end
+
+  def filter_map(&blk)
+    return to_enum(:filter_map) unless blk
+
+    ary = []
+    self.each do |x|
+      x = blk.call(x)
+      ary.push x if x
+    end
+    ary
+  end
+
+  alias filter select
+
+  ##
+  # call-seq:
+  #   enum.tally -> a_hash
+  #
+  # Tallys the collection.  Returns a hash where the keys are the
+  # elements and the values are numbers of elements in the collection
+  # that correspond to the key.
+  #
+  #    ["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1}
+  def tally
+    hash = {}
+    self.each do |x|
+      hash[x] = (hash[x]||0)+1
+    end
+    hash
+  end
 end
index 64b1bbd..f0301a2 100644 (file)
@@ -186,8 +186,13 @@ assert("Enumerable#to_h") do
   h = c.new.to_h
   assert_equal Hash, h.class
   assert_equal h0, h
-  # mruby-enum-ext also provides nil.to_h
-  assert_equal Hash.new, nil.to_h
-
   assert_equal({1=>4,3=>8}, c.new.to_h{|k,v|[k,v*2]})
 end
+
+assert("Enumerable#filter_map") do
+  assert_equal [4, 8, 12, 16, 20], (1..10).filter_map{|i| i * 2 if i%2==0}
+end
+
+assert("Enumerable#tally") do
+  assert_equal({"a"=>1, "b"=>2, "c"=>1}, ["a", "b", "c", "b"].tally)
+end
index 8757a15..abcc54e 100644 (file)
@@ -2,6 +2,5 @@ MRuby::Gem::Specification.new('mruby-enumerator') do |spec|
   spec.license = 'MIT'
   spec.author  = 'mruby developers'
   spec.add_dependency('mruby-fiber', :core => 'mruby-fiber')
-  spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext'
   spec.summary = 'Enumerator class'
 end
index 4576872..5a98dc9 100644 (file)
@@ -89,7 +89,6 @@ class Enumerator
   include Enumerable
 
   ##
-  # @overload initialize(size = nil, &block)
   # @overload initialize(obj, method = :each, *args)
   #
   # Creates a new Enumerator object, which can be used as an
@@ -244,9 +243,10 @@ class Enumerator
   #
   # === Examples
   #
-  #   "Hello, world!".scan(/\w+/)                     #=> ["Hello", "world"]
-  #   "Hello, world!".to_enum(:scan, /\w+/).to_a      #=> ["Hello", "world"]
-  #   "Hello, world!".to_enum(:scan).each(/\w+/).to_a #=> ["Hello", "world"]
+  #   Array.new(3)                     #=> [nil, nil, nil]
+  #   Array.new(3) { |i| i }           #=> [0, 1, 2]
+  #   Array.to_enum(:new, 3).to_a      #=> [0, 1, 2]
+  #   Array.to_enum(:new).each(3).to_a #=> [0, 1, 2]
   #
   #   obj = Object.new
   #
@@ -555,6 +555,46 @@ class Enumerator
       self
     end
   end
+
+  ##
+  # call-seq:
+  #    Enumerator.produce(initial = nil) { |val| } -> enumerator
+  #
+  # Creates an infinite enumerator from any block, just called over and
+  # over.  Result of the previous iteration is passed to the next one.
+  # If +initial+ is provided, it is passed to the first iteration, and
+  # becomes the first element of the enumerator; if it is not provided,
+  # first iteration receives +nil+, and its result becomes first
+  # element of the iterator.
+  #
+  # Raising StopIteration from the block stops an iteration.
+  #
+  # Examples of usage:
+  #
+  #   Enumerator.produce(1, &:succ)   # => enumerator of 1, 2, 3, 4, ....
+  #
+  #   Enumerator.produce { rand(10) } # => infinite random number sequence
+  #
+  #   ancestors = Enumerator.produce(node) { |prev| node = prev.parent or raise StopIteration }
+  #   enclosing_section = ancestors.find { |n| n.type == :section }
+  def Enumerator.produce(init=NONE, &block)
+    raise ArgumentError, "no block given" if block.nil?
+    Enumerator.new do |y|
+      if init == NONE
+        val = nil
+      else
+        val = init
+        y.yield(val)
+      end
+      begin
+        while true
+          y.yield(val = block.call(val))
+        end
+      rescue StopIteration
+        # do nothing
+      end
+    end
+  end
 end
 
 module Kernel
@@ -562,15 +602,10 @@ module Kernel
   # call-seq:
   #   obj.to_enum(method = :each, *args)                 -> enum
   #   obj.enum_for(method = :each, *args)                -> enum
-  #   obj.to_enum(method = :each, *args) {|*args| block} -> enum
-  #   obj.enum_for(method = :each, *args){|*args| block} -> enum
   #
   # Creates a new Enumerator which will enumerate by calling +method+ on
   # +obj+, passing +args+ if any.
   #
-  # If a block is given, it will be used to calculate the size of
-  # the enumerator without the need to iterate it (see Enumerator#size).
-  #
   # === Examples
   #
   #   str = "xyz"
@@ -588,17 +623,14 @@ module Kernel
   # It is typical to call to_enum when defining methods for
   # a generic Enumerable, in case no block is passed.
   #
-  # Here is such an example, with parameter passing and a sizing block:
+  # Here is such an example with parameter passing:
   #
   #     module Enumerable
   #       # a generic method to repeat the values of any enumerable
   #       def repeat(n)
   #         raise ArgumentError, "#{n} is negative!" if n < 0
   #         unless block_given?
-  #           return to_enum(__method__, n) do # __method__ is :repeat here
-  #             sz = size     # Call size and multiply by n...
-  #             sz * n if sz  # but return nil if size itself is nil
-  #           end
+  #           return to_enum(__method__, n) # __method__ is :repeat here
   #         end
   #         each do |*val|
   #           n.times { yield *val }
index d609cad..ecd6c4d 100644 (file)
@@ -6,6 +6,17 @@ class << @obj
   end
 end
 
+def assert_take(exp, enumerator)
+  result = []
+  n = exp.size
+  enumerator.each do |v|
+    result << v
+    n -= 1
+    break if n == 0
+  end if n > 0
+  assert_equal exp, result
+end
+
 assert 'Enumerator.class' do
   assert_equal Class, Enumerator.class
 end
@@ -19,7 +30,7 @@ assert 'Enumerator.new' do
   assert_equal [:x,:y,:z], [:x,:y,:z].each.map{|i| i}.sort
   assert_equal [[:x,1],[:y,2]], {x:1, y:2}.each.map{|i| i}.sort
   assert_equal [1,2,3], @obj.to_enum(:foo, 1,2,3).to_a
-  assert_equal [1,2,3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.take(3)
+  assert_take [1,2,3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }
   assert_raise(ArgumentError) { Enumerator.new }
 
   # examples
@@ -30,7 +41,7 @@ assert 'Enumerator.new' do
       a, b = b, a + b
     end
   end
-  assert_equal [1,1,2,3,5,8,13,21,34,55], fib.take(10)
+  assert_take [1,1,2,3,5,8,13,21,34,55], fib
 end
 
 assert 'Enumerator#initialize_copy' do
@@ -549,3 +560,41 @@ assert 'Enumerable#zip' do
 
   assert_raise(TypeError) { [1].zip(1) }
 end
+
+assert 'Enumerator.produce' do
+  assert_raise(ArgumentError) { Enumerator.produce }
+
+  # Without initial object
+  passed_args = []
+  enum = Enumerator.produce {|obj| passed_args << obj; (obj || 0).succ }
+  assert_equal Enumerator, enum.class 
+  assert_take [1, 2, 3], enum
+  assert_equal [nil, 1, 2], passed_args
+
+  # With initial object
+  passed_args = []
+  enum = Enumerator.produce(1) {|obj| passed_args << obj; obj.succ }
+  assert_take [1, 2, 3], enum
+  assert_equal [1, 2], passed_args
+
+  # Raising StopIteration
+  words = %w[The quick brown fox jumps over the lazy dog]
+  enum = Enumerator.produce { words.shift or raise StopIteration }
+  assert_equal %w[The quick brown fox jumps over the lazy dog], enum.to_a
+
+  # Raising StopIteration
+  object = [[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], "stuv", "wxyz"]
+  enum = Enumerator.produce(object) {|obj|
+    obj.respond_to?(:first) or raise StopIteration
+    obj.first
+  }
+  assert_nothing_raised {
+    assert_equal [
+      [[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], "stuv", "wxyz"],
+      [[["abc", "def"], "ghi", "jkl"], "mno", "pqr"],
+      [["abc", "def"], "ghi", "jkl"],
+      ["abc", "def"],
+      "abc",
+    ], enum.to_a
+  }
+end
index 170abb6..e0ea28a 100644 (file)
@@ -8,6 +8,7 @@ mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state)
   struct mrb_jmpbuf *prev_jmp = mrb->jmp;
   struct mrb_jmpbuf c_jmp;
   mrb_value result = mrb_nil_value();
+  int ai = mrb_gc_arena_save(mrb);
 
   if (state) { *state = FALSE; }
 
@@ -22,6 +23,7 @@ mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state)
     if (state) { *state = TRUE; }
   } MRB_END_EXC(&c_jmp);
 
+  mrb_gc_arena_restore(mrb, ai);
   mrb_gc_protect(mrb, result);
   return result;
 }
@@ -32,6 +34,7 @@ mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure,
   struct mrb_jmpbuf *prev_jmp = mrb->jmp;
   struct mrb_jmpbuf c_jmp;
   mrb_value result;
+  int ai = mrb_gc_arena_save(mrb);
 
   MRB_TRY(&c_jmp) {
     mrb->jmp = &c_jmp;
@@ -39,11 +42,15 @@ mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure,
     mrb->jmp = prev_jmp;
   } MRB_CATCH(&c_jmp) {
     mrb->jmp = prev_jmp;
+    mrb_gc_arena_restore(mrb, ai);
     ensure(mrb, e_data);
     MRB_THROW(mrb->jmp); /* rethrow catched exceptions */
   } MRB_END_EXC(&c_jmp);
 
+  mrb_gc_arena_restore(mrb, ai);
+  mrb_gc_protect(mrb, result);
   ensure(mrb, e_data);
+  mrb_gc_arena_restore(mrb, ai);
   mrb_gc_protect(mrb, result);
   return result;
 }
@@ -64,6 +71,7 @@ mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_fun
   mrb_value result;
   mrb_bool error_matched = FALSE;
   mrb_int i;
+  int ai = mrb_gc_arena_save(mrb);
 
   MRB_TRY(&c_jmp) {
     mrb->jmp = &c_jmp;
@@ -82,9 +90,11 @@ mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_fun
     if (!error_matched) { MRB_THROW(mrb->jmp); }
 
     mrb->exc = NULL;
+    mrb_gc_arena_restore(mrb, ai);
     result = rescue(mrb, r_data);
   } MRB_END_EXC(&c_jmp);
 
+  mrb_gc_arena_restore(mrb, ai);
   mrb_gc_protect(mrb, result);
   return result;
 }
index fa687d6..eaf07ca 100644 (file)
@@ -9,214 +9,6 @@
 mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p);
 mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self);
 
-static struct mrb_irep *
-get_closure_irep(mrb_state *mrb, int level)
-{
-  struct RProc *proc = mrb->c->ci[-1].proc;
-
-  while (level--) {
-    if (!proc) return NULL;
-    proc = proc->upper;
-  }
-  if (!proc) return NULL;
-  if (MRB_PROC_CFUNC_P(proc)) {
-    return NULL;
-  }
-  return proc->body.irep;
-}
-
-/* search for irep lev above the bottom */
-static mrb_irep*
-search_irep(mrb_irep *top, int bnest, int lev, mrb_irep *bottom)
-{
-  int i;
-
-  for (i=0; i<top->rlen; i++) {
-    mrb_irep* tmp = top->reps[i];
-
-    if (tmp == bottom) return top;
-    tmp = search_irep(tmp, bnest-1, lev, bottom);
-    if (tmp) {
-      if (bnest == lev) return top;
-      return tmp;
-    }
-  }
-  return NULL;
-}
-
-static uint16_t
-search_variable(mrb_state *mrb, mrb_sym vsym, int bnest)
-{
-  mrb_irep *virep;
-  int level;
-  int pos;
-
-  for (level = 0; (virep = get_closure_irep(mrb, level)); level++) {
-    if (virep->lv == NULL) {
-      continue;
-    }
-    for (pos = 0; pos < virep->nlocals - 1; pos++) {
-      if (vsym == virep->lv[pos].name) {
-        return (pos+1)<<8 | (level+bnest);
-      }
-    }
-  }
-
-  return 0;
-}
-
-static int
-irep_argc(mrb_irep *irep)
-{
-  mrb_code c;
-
-  c = irep->iseq[0];
-  if (c == OP_ENTER) {
-    mrb_aspec ax = PEEK_W(irep->iseq+1);
-    /* extra 1 means a slot for block */
-    return MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1;
-  }
-  return 0;
-}
-
-static mrb_bool
-potential_upvar_p(struct mrb_locals *lv, uint16_t v, int argc, uint16_t nlocals)
-{
-  if (v >= nlocals) return FALSE;
-  /* skip arguments  */
-  if (v < argc+1) return FALSE;
-  return TRUE;
-}
-
-extern uint8_t mrb_insn_size[];
-extern uint8_t mrb_insn_size1[];
-extern uint8_t mrb_insn_size2[];
-extern uint8_t mrb_insn_size3[];
-
-static void
-patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest, mrb_irep *top)
-{
-  int i;
-  uint32_t a;
-  uint16_t b;
-  uint8_t c;
-  mrb_code insn;
-  int argc = irep_argc(irep);
-
-  for (i = 0; i < irep->ilen; ) {
-    insn = irep->iseq[i];
-    switch(insn){
-    case OP_EPUSH:
-      b = PEEK_S(irep->iseq+i+1);
-      patch_irep(mrb, irep->reps[b], bnest + 1, top);
-      break;
-
-    case OP_LAMBDA:
-    case OP_BLOCK:
-      a = PEEK_B(irep->iseq+i+1);
-      b = PEEK_B(irep->iseq+i+2);
-      patch_irep(mrb, irep->reps[b], bnest + 1, top);
-      break;
-
-    case OP_SEND:
-      b = PEEK_B(irep->iseq+i+2);
-      c = PEEK_B(irep->iseq+i+3);
-      if (c != 0) {
-        break;
-      }
-      else {
-        uint16_t arg = search_variable(mrb, irep->syms[b], bnest);
-        if (arg != 0) {
-          /* must replace */
-          irep->iseq[i] = OP_GETUPVAR;
-          irep->iseq[i+2] = arg >> 8;
-          irep->iseq[i+3] = arg & 0xff;
-        }
-      }
-      break;
-
-    case OP_MOVE:
-      a = PEEK_B(irep->iseq+i+1);
-      b = PEEK_B(irep->iseq+i+2);
-      /* src part */
-      if (potential_upvar_p(irep->lv, b, argc, irep->nlocals)) {
-        uint16_t arg = search_variable(mrb, irep->lv[b - 1].name, bnest);
-        if (arg != 0) {
-          /* must replace */
-          irep->iseq[i] = insn = OP_GETUPVAR;
-          irep->iseq[i+2] = arg >> 8;
-          irep->iseq[i+3] = arg & 0xff;
-        }
-      }
-      /* dst part */
-      if (potential_upvar_p(irep->lv, a, argc, irep->nlocals)) {
-        uint16_t arg = search_variable(mrb, irep->lv[a - 1].name, bnest);
-        if (arg != 0) {
-          /* must replace */
-          irep->iseq[i] = insn = OP_SETUPVAR;
-          irep->iseq[i+1] = (mrb_code)b;
-          irep->iseq[i+2] = arg >> 8;
-          irep->iseq[i+3] = arg & 0xff;
-        }
-      }
-      break;
-
-    case OP_GETUPVAR:
-      a = PEEK_B(irep->iseq+i+1);
-      b = PEEK_B(irep->iseq+i+2);
-      c = PEEK_B(irep->iseq+i+3);
-      {
-        int lev = c+1;
-        mrb_irep *tmp = search_irep(top, bnest, lev, irep);
-        if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) {
-          uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest);
-          if (arg != 0) {
-            /* must replace */
-            irep->iseq[i] = OP_GETUPVAR;
-            irep->iseq[i+2] = arg >> 8;
-            irep->iseq[i+3] = arg & 0xff;
-          }
-        }
-      }
-      break;
-
-    case OP_SETUPVAR:
-      a = PEEK_B(irep->iseq+i+1);
-      b = PEEK_B(irep->iseq+i+2);
-      c = PEEK_B(irep->iseq+i+3);
-      {
-        int lev = c+1;
-        mrb_irep *tmp = search_irep(top, bnest, lev, irep);
-        if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) {
-          uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest);
-          if (arg != 0) {
-            /* must replace */
-            irep->iseq[i] = OP_SETUPVAR;
-            irep->iseq[i+1] = a;
-            irep->iseq[i+2] = arg >> 8;
-            irep->iseq[i+3] = arg & 0xff;
-          }
-        }
-      }
-      break;
-
-    case OP_EXT1:
-      insn = PEEK_B(irep->iseq+i+1);
-      i += mrb_insn_size1[insn]+1;
-      continue;
-    case OP_EXT2:
-      insn = PEEK_B(irep->iseq+i+1);
-      i += mrb_insn_size2[insn]+1;
-      continue;
-    case OP_EXT3:
-      insn = PEEK_B(irep->iseq+i+1);
-      i += mrb_insn_size3[insn]+1;
-      continue;
-    }
-    i+=mrb_insn_size[insn];
-  }
-}
-
 void mrb_codedump_all(mrb_state*, struct RProc*);
 
 static struct RProc*
@@ -235,12 +27,13 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
   }
 
   cxt = mrbc_context_new(mrb);
-  cxt->lineno = (short)line;
+  cxt->lineno = (uint16_t)line;
 
   mrbc_filename(mrb, cxt, file ? file : "(eval)");
   cxt->capture_errors = TRUE;
   cxt->no_optimize = TRUE;
-  cxt->on_eval = TRUE;
+  ci = (mrb->c->ci > mrb->c->cibase) ? mrb->c->ci - 1 : mrb->c->cibase;
+  cxt->upper = ci->proc && MRB_PROC_CFUNC_P(ci->proc) ? NULL : ci->proc;
 
   p = mrb_parse_nstring(mrb, s, len, cxt);
 
@@ -254,15 +47,15 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
     mrb_value str;
 
     if (file) {
-      str = mrb_format(mrb, " file %S line %S: %S",
-                       mrb_str_new_cstr(mrb, file),
-                       mrb_fixnum_value(p->error_buffer[0].lineno),
-                       mrb_str_new_cstr(mrb, p->error_buffer[0].message));
+      str = mrb_format(mrb, "file %s line %d: %s",
+                       file,
+                       p->error_buffer[0].lineno,
+                       p->error_buffer[0].message);
     }
     else {
-      str = mrb_format(mrb, " line %S: %S",
-                       mrb_fixnum_value(p->error_buffer[0].lineno),
-                       mrb_str_new_cstr(mrb, p->error_buffer[0].message));
+      str = mrb_format(mrb, "line %d: %s",
+                       p->error_buffer[0].lineno,
+                       p->error_buffer[0].message);
     }
     mrb_parser_free(p);
     mrbc_context_free(mrb, cxt);
@@ -295,7 +88,7 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
       e->mid = ci->mid;
       e->stack = ci[1].stackent;
       e->cxt = mrb->c;
-      MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals);
+      MRB_ENV_SET_LEN(e, ci->proc->body.irep->nlocals);
       bidx = ci->argc;
       if (ci->argc < 0) bidx = 2;
       else bidx += 1;
@@ -308,7 +101,6 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
   }
   proc->upper = ci->proc;
   mrb->c->ci->target_class = target_class;
-  patch_irep(mrb, proc->body.irep, 0, proc->body.irep);
   /* mrb_codedump_all(mrb, proc); */
 
   mrb_parser_free(p);
@@ -387,7 +179,7 @@ void
 mrb_mruby_eval_gem_init(mrb_state* mrb)
 {
   mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3));
-  mrb_define_method(mrb, mrb->kernel_module, "instance_eval", f_instance_eval, MRB_ARGS_ARG(1, 2));
+  mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
 }
 
 void
index 4d7dd46..639ed68 100644 (file)
@@ -80,7 +80,7 @@ assert('Kernel.#eval(string) context') do
   assert_equal('class') { obj.const_string }
 end
 
-assert('Object#instance_eval with begin-rescue-ensure execution order') do
+assert('BasicObject#instance_eval with begin-rescue-ensure execution order') do
   class HellRaiser
     def raise_hell
       order = [:enter_raise_hell]
@@ -100,7 +100,7 @@ assert('Object#instance_eval with begin-rescue-ensure execution order') do
   assert_equal([:enter_raise_hell, :begin, :rescue, :ensure], hell_raiser.raise_hell)
 end
 
-assert('Kernel#instance_eval() to define singleton methods Issue #3141') do
+assert('BasicObject#instance_eval to define singleton methods Issue #3141') do
   foo_class = Class.new do
     def bar(x)
       instance_eval "def baz; #{x}; end"
@@ -130,3 +130,24 @@ Proc.new { foo }
 EOS
   }
 end
+
+assert('Calling the same method as the variable name') do
+  hoge = Object.new
+  def hoge.fuga
+    "Hit!"
+  end
+  assert_equal("Hit!") { fuga = "Miss!"; eval "hoge.fuga" }
+  assert_equal("Hit!") { fuga = "Miss!"; -> { eval "hoge.fuga" }.call }
+  assert_equal("Hit!") { -> { fuga = "Miss!"; eval "hoge.fuga" }.call }
+  assert_equal("Hit!") { fuga = "Miss!"; eval("-> { hoge.fuga }").call }
+end
+
+assert('Access numbered parameter from eval') do
+  hoge = Object.new
+  def hoge.fuga(a, &b)
+    b.call(a)
+  end
+  assert_equal(6) {
+    hoge.fuga(3) { _1 + eval("_1") }
+  }
+end
index 05c9296..4ff2f93 100644 (file)
@@ -4,12 +4,17 @@
 static mrb_value
 f_exit(mrb_state *mrb, mrb_value self)
 {
-  mrb_int i = EXIT_SUCCESS;
+  mrb_value status = mrb_true_value();
+  int istatus;
+
+  mrb_get_args(mrb, "|o", &status);
+  istatus = mrb_true_p(status) ? EXIT_SUCCESS :
+            mrb_false_p(status) ? EXIT_FAILURE :
+            (int)mrb_int(mrb, status);
+  exit(istatus);
 
-  mrb_get_args(mrb, "|i", &i);
-  exit((int)i);
   /* not reached */
-  return mrb_nil_value();
+  return status;
 }
 
 void
index 17ce77c..00ee7c2 100644 (file)
@@ -72,14 +72,11 @@ fiber_init(mrb_state *mrb, mrb_value self)
   mrb_value blk;
   size_t slen;
 
-  mrb_get_args(mrb, "&", &blk);
+  mrb_get_args(mrb, "&!", &blk);
 
   if (f->cxt) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "cannot initialize twice");
   }
-  if (mrb_nil_p(blk)) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Fiber object without a block");
-  }
   p = mrb_proc_ptr(blk);
   if (MRB_PROC_CFUNC_P(p)) {
     mrb_raise(mrb, E_FIBER_ERROR, "tried to create Fiber from C defined method");
@@ -191,14 +188,21 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr
 
   fiber_check_cfunc(mrb, c);
   status = c->status;
-  if (resume && status == MRB_FIBER_TRANSFERRED) {
-    mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber");
-  }
-  if (status == MRB_FIBER_RUNNING || status == MRB_FIBER_RESUMED) {
+  switch (status) {
+  case MRB_FIBER_TRANSFERRED:
+    if (resume) {
+      mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber");
+    }
+    break;
+  case MRB_FIBER_RUNNING:
+  case MRB_FIBER_RESUMED:
     mrb_raise(mrb, E_FIBER_ERROR, "double resume");
-  }
-  if (status == MRB_FIBER_TERMINATED) {
+    break;
+  case MRB_FIBER_TERMINATED:
     mrb_raise(mrb, E_FIBER_ERROR, "resuming dead fiber");
+    break;
+  default:
+    break;
   }
   old_c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED;
   c->prev = resume ? mrb->c : (c->prev ? c->prev : mrb->root_c);
@@ -287,10 +291,9 @@ mrb_fiber_alive_p(mrb_state *mrb, mrb_value self)
 static mrb_value
 fiber_eq(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other;
-  mrb_get_args(mrb, "o", &other);
+  mrb_value other = mrb_get_arg1(mrb);
 
-  if (mrb_type(other) != MRB_TT_FIBER) {
+  if (!mrb_fiber_p(other)) {
     return mrb_false_value();
   }
   return mrb_bool_value(fiber_ptr(self) == fiber_ptr(other));
@@ -405,7 +408,7 @@ mrb_mruby_fiber_gem_init(mrb_state* mrb)
   c = mrb_define_class(mrb, "Fiber", mrb->object_class);
   MRB_SET_INSTANCE_TT(c, MRB_TT_FIBER);
 
-  mrb_define_method(mrb, c, "initialize", fiber_init,    MRB_ARGS_NONE());
+  mrb_define_method(mrb, c, "initialize", fiber_init,    MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
   mrb_define_method(mrb, c, "resume",     fiber_resume,  MRB_ARGS_ANY());
   mrb_define_method(mrb, c, "transfer",   fiber_transfer, MRB_ARGS_ANY());
   mrb_define_method(mrb, c, "alive?",     fiber_alive_p, MRB_ARGS_NONE());
index d063a0a..b6ecb79 100644 (file)
@@ -76,7 +76,7 @@ assert('Fiber iteration') do
 end
 
 assert('Fiber with splat in the block argument list') {
-  Fiber.new{|*x|x}.resume(1) == [1]
+  assert_equal([1], Fiber.new{|*x|x}.resume(1))
 }
 
 assert('Fiber raises on resume when dead') do
index 103410a..e0681c1 100644 (file)
@@ -2,7 +2,5 @@ MRuby::Gem::Specification.new('mruby-hash-ext') do |spec|
   spec.license = 'MIT'
   spec.author  = 'mruby developers'
   spec.summary = 'Hash class extension'
-  spec.add_dependency 'mruby-enum-ext', core: 'mruby-enum-ext'
   spec.add_dependency 'mruby-array-ext', core: 'mruby-array-ext'
-  spec.add_test_dependency 'mruby-enumerator', core: 'mruby-enumerator'
 end
index 547f340..33e2dcb 100644 (file)
@@ -494,4 +494,7 @@ class Hash
       self.fetch(k, &block)
     end
   end
+
+  alias filter select
+  alias filter! select!
 end
index e611266..75ebd41 100644 (file)
@@ -53,10 +53,8 @@ hash_slice(mrb_state *mrb, mrb_value hash)
   mrb_int argc, i;
 
   mrb_get_args(mrb, "*", &argv, &argc);
-  if (argc == 0) {
-    return mrb_hash_new_capa(mrb, argc);
-  }
   result = mrb_hash_new_capa(mrb, argc);
+  if (argc == 0) return result; /* empty hash */
   for (i = 0; i < argc; i++) {
     mrb_value key = argv[i];
     mrb_value val;
index b5d0aaa..fdf4c57 100644 (file)
@@ -269,10 +269,8 @@ assert("Hash#transform_keys") do
                h.transform_keys{|k| k+"!"})
   assert_equal({1 => 100, 2 => 200},
                h.transform_keys{|k|k.to_i})
-  assert_equal({"1.0" => 100, "2.1" => 200},
-               h.transform_keys.with_index{|k, i| "#{k}.#{i}"})
-  assert_equal(h, h.transform_keys!{|k|k.to_i})
-  assert_equal(h, {1 => 100, 2 => 200})
+  assert_same(h, h.transform_keys!{|k|k.to_i})
+  assert_equal({1 => 100, 2 => 200}, h)
 end
 
 assert("Hash#transform_values") do
@@ -281,9 +279,7 @@ assert("Hash#transform_values") do
                h.transform_values{|v| v * v + 1})
   assert_equal({a: "1", b: "2", c: "3"},
                h.transform_values{|v|v.to_s})
-  assert_equal({a: "1.0", b: "2.1", c: "3.2"},
-               h.transform_values.with_index{|v, i| "#{v}.#{i}"})
-  assert_equal(h, h.transform_values!{|v|v.to_s})
+  assert_same(h, h.transform_values!{|v|v.to_s})
   assert_equal({a: "1", b: "2", c: "3"}, h)
 end
 
index 51804ae..5d307dc 100644 (file)
@@ -8,8 +8,7 @@ istruct_test_initialize(mrb_state *mrb, mrb_value self)
 {
   char *string = (char*)mrb_istruct_ptr(self);
   mrb_int size = mrb_istruct_size();
-  mrb_value object;
-  mrb_get_args(mrb, "o", &object);
+  mrb_value object = mrb_get_arg1(mrb);
 
   if (mrb_fixnum_p(object)) {
     strncpy(string, "fixnum", size-1);
@@ -45,8 +44,8 @@ istruct_test_length(mrb_state *mrb, mrb_value self)
 static mrb_value
 istruct_test_test_receive(mrb_state *mrb, mrb_value self)
 {
-  mrb_value object;
-  mrb_get_args(mrb, "o", &object);
+  mrb_value object = mrb_get_arg1(mrb);
+
   if (mrb_obj_class(mrb, object) != mrb_class_get(mrb, "InlineStructTest"))
   {
     mrb_raise(mrb, E_TYPE_ERROR, "Expected InlineStructTest");
diff --git a/third-party/mruby/mrbgems/mruby-io/.gitignore b/third-party/mruby/mrbgems/mruby-io/.gitignore
deleted file mode 100644 (file)
index ceeb05b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/tmp
diff --git a/third-party/mruby/mrbgems/mruby-io/.travis.yml b/third-party/mruby/mrbgems/mruby-io/.travis.yml
deleted file mode 100644 (file)
index ffe2272..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-script:
-  - "ruby run_test.rb all test"
index 256fb81..2c5b762 100644 (file)
@@ -1,7 +1,5 @@
 mruby-io
 ========
-[![Build Status](https://travis-ci.org/iij/mruby-io.svg?branch=master)](https://travis-ci.org/iij/mruby-io)
-
 
 `IO` and `File` classes for mruby
 
@@ -9,7 +7,7 @@ mruby-io
 Add the line below to your `build_config.rb`:
 
 ```
-  conf.gem :github => 'iij/mruby-io'
+  conf.gem core: 'mruby-io'
 ```
 
 ## Implemented methods
@@ -173,6 +171,7 @@ Add the line below to your `build_config.rb`:
 ## License
 
 Copyright (c) 2013 Internet Initiative Japan Inc.
+Copyright (c) 2017 mruby developers
 
 Permission is hereby granted, free of charge, to any person obtaining a 
 copy of this software and associated documentation files (the "Software"), 
index ba08815..dfff8e0 100644 (file)
@@ -5,10 +5,24 @@
 #ifndef MRUBY_IO_H
 #define MRUBY_IO_H
 
+#include <mruby.h>
+
+#ifdef MRB_DISABLE_STDIO
+# error IO and File conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
+#endif
+
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
+#if defined(MRB_WITHOUT_IO_PREAD_PWRITE)
+# undef MRB_WITH_IO_PREAD_PWRITE
+#elif !defined(MRB_WITH_IO_PREAD_PWRITE)
+# if defined(__unix__) || defined(__MACH__)
+#  define MRB_WITH_IO_PREAD_PWRITE
+# endif
+#endif
+
 struct mrb_io {
   int fd;   /* file descriptor, or -1 */
   int fd2;  /* file descriptor to write if it's different from fd, or -1 */
@@ -19,18 +33,36 @@ struct mrb_io {
                is_socket:1;
 };
 
-#define FMODE_READABLE             0x00000001
-#define FMODE_WRITABLE             0x00000002
-#define FMODE_READWRITE            (FMODE_READABLE|FMODE_WRITABLE)
-#define FMODE_BINMODE              0x00000004
-#define FMODE_APPEND               0x00000040
-#define FMODE_CREATE               0x00000080
-#define FMODE_TRUNC                0x00000800
+#define MRB_O_RDONLY            0x0000
+#define MRB_O_WRONLY            0x0001
+#define MRB_O_RDWR              0x0002
+#define MRB_O_ACCMODE           (MRB_O_RDONLY | MRB_O_WRONLY | MRB_O_RDWR)
+#define MRB_O_NONBLOCK          0x0004
+#define MRB_O_APPEND            0x0008
+#define MRB_O_SYNC              0x0010
+#define MRB_O_NOFOLLOW          0x0020
+#define MRB_O_CREAT             0x0040
+#define MRB_O_TRUNC             0x0080
+#define MRB_O_EXCL              0x0100
+#define MRB_O_NOCTTY            0x0200
+#define MRB_O_DIRECT            0x0400
+#define MRB_O_BINARY            0x0800
+#define MRB_O_SHARE_DELETE      0x1000
+#define MRB_O_TMPFILE           0x2000
+#define MRB_O_NOATIME           0x4000
+#define MRB_O_DSYNC             0x00008000
+#define MRB_O_RSYNC             0x00010000
+
+#define MRB_O_RDONLY_P(f)       ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_RDONLY))
+#define MRB_O_WRONLY_P(f)       ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_WRONLY))
+#define MRB_O_RDWR_P(f)         ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_RDWR))
+#define MRB_O_READABLE_P(f)     ((mrb_bool)((((f) & MRB_O_ACCMODE) | 2) == 2))
+#define MRB_O_WRITABLE_P(f)     ((mrb_bool)(((((f) & MRB_O_ACCMODE) + 1) & 2) == 2))
 
 #define E_IO_ERROR                 (mrb_class_get(mrb, "IOError"))
 #define E_EOF_ERROR                (mrb_class_get(mrb, "EOFError"))
 
-mrb_value mrb_io_fileno(mrb_state *mrb, mrb_value io);
+int mrb_io_fileno(mrb_state *mrb, mrb_value io);
 
 #if defined(__cplusplus)
 } /* extern "C" { */
index d799645..d0c8fb0 100644 (file)
@@ -1,18 +1,12 @@
 MRuby::Gem::Specification.new('mruby-io') do |spec|
   spec.license = 'MIT'
-  spec.authors = 'Internet Initiative Japan Inc.'
+  spec.authors = ['Internet Initiative Japan Inc.', 'mruby developers']
   spec.summary = 'IO and File class'
 
   spec.cc.include_paths << "#{build.root}/src"
 
-  case RUBY_PLATFORM
-  when /mingw|mswin/
-    spec.linker.libraries += ['Ws2_32']
-    #spec.cc.include_paths += ["C:/Windows/system/include"]
-    spec.linker.library_paths += ["C:/Windows/system"]
-  end
-  if build.kind_of?(MRuby::CrossBuild) && %w(x86_64-w64-mingw32 i686-w64-mingw32).include?(build.host_target)
-    spec.linker.libraries += ['ws2_32']
+  if for_windows?
+    spec.linker.libraries << "ws2_32"
   end
   spec.add_test_dependency 'mruby-time', core: 'mruby-time'
 end
index 514efc1..d3a4b1e 100644 (file)
@@ -1,9 +1,4 @@
 class File < IO
-  class FileError < Exception; end
-  class NoFileError < FileError; end
-  class UnableToStat < FileError; end
-  class PermissionError < FileError; end
-
   attr_accessor :path
 
   def initialize(fd_or_path, mode = "r", perm = 0666)
@@ -60,46 +55,46 @@ class File < IO
     s
   end
 
-  def self.expand_path(path, default_dir = '.')
-    def concat_path(path, base_path)
-      if path[0] == "/" || path[1] == ':' # Windows root!
-        expanded_path = path
-      elsif path[0] == "~"
-        if (path[1] == "/" || path[1] == nil)
-          dir = path[1, path.size]
-          home_dir = _gethome
-
-          unless home_dir
-            raise ArgumentError, "couldn't find HOME environment -- expanding '~'"
-          end
+  def self._concat_path(path, base_path)
+    if path[0] == "/" || path[1] == ':' # Windows root!
+      expanded_path = path
+    elsif path[0] == "~"
+      if (path[1] == "/" || path[1] == nil)
+        dir = path[1, path.size]
+        home_dir = _gethome
 
-          expanded_path = home_dir
-          expanded_path += dir if dir
-          expanded_path += "/"
-        else
-          splitted_path = path.split("/")
-          user = splitted_path[0][1, splitted_path[0].size]
-          dir = "/" + splitted_path[1, splitted_path.size].join("/")
+        unless home_dir
+          raise ArgumentError, "couldn't find HOME environment -- expanding '~'"
+        end
 
-          home_dir = _gethome(user)
+        expanded_path = home_dir
+        expanded_path += dir if dir
+        expanded_path += "/"
+      else
+        splitted_path = path.split("/")
+        user = splitted_path[0][1, splitted_path[0].size]
+        dir = "/" + splitted_path[1, splitted_path.size].join("/")
 
-          unless home_dir
-            raise ArgumentError, "user #{user} doesn't exist"
-          end
+        home_dir = _gethome(user)
 
-          expanded_path = home_dir
-          expanded_path += dir if dir
-          expanded_path += "/"
+        unless home_dir
+          raise ArgumentError, "user #{user} doesn't exist"
         end
-      else
-        expanded_path = concat_path(base_path, _getwd)
-        expanded_path += "/" + path
-      end
 
-      expanded_path
+        expanded_path = home_dir
+        expanded_path += dir if dir
+        expanded_path += "/"
+      end
+    else
+      expanded_path = _concat_path(base_path, _getwd)
+      expanded_path += "/" + path
     end
 
-    expanded_path = concat_path(path, default_dir)
+    expanded_path
+  end
+
+  def self.expand_path(path, default_dir = '.')
+    expanded_path = _concat_path(path, default_dir)
     drive_prefix = ""
     if File::ALT_SEPARATOR && expanded_path.size > 2 &&
         ("A".."Z").include?(expanded_path[0].upcase) && expanded_path[1] == ":"
index a68ee25..bd77d53 100644 (file)
@@ -1,21 +1,5 @@
 class File
   module Constants
-    RDONLY   = 0
-    WRONLY   = 1
-    RDWR     = 2
-    NONBLOCK = 4
-    APPEND   = 8
-
-    BINARY   = 0
-    SYNC     = 128
-    NOFOLLOW = 256
-    CREAT    = 512
-    TRUNC    = 1024
-    EXCL     = 2048
-
-    NOCTTY   = 131072
-    DSYNC    = 4194304
-
     FNM_SYSCASE  = 0
     FNM_NOESCAPE = 1
     FNM_PATHNAME = 2
index 6211bf1..e597db8 100644 (file)
@@ -123,8 +123,8 @@ class IO
 
   def write(string)
     str = string.is_a?(String) ? string : string.to_s
-    return str.size unless str.size > 0
-    if 0 < @buf.length
+    return 0 if str.empty?
+    unless @buf.empty?
       # reset real pos ignore buf
       seek(pos, SEEK_SET)
     end
@@ -140,8 +140,8 @@ class IO
   def eof?
     _check_readable
     begin
-      buf = _read_buf
-      return buf.size == 0
+      _read_buf
+      return @buf.empty?
     rescue EOFError
       return true
     end
@@ -150,7 +150,7 @@ class IO
 
   def pos
     raise IOError if closed?
-    sysseek(0, SEEK_CUR) - @buf.length
+    sysseek(0, SEEK_CUR) - @buf.bytesize
   end
   alias_method :tell, :pos
 
@@ -170,16 +170,16 @@ class IO
   end
 
   def _read_buf
-    return @buf if @buf && @buf.size > 0
-    @buf = sysread(BUF_SIZE)
+    return @buf if @buf && @buf.bytesize > 0
+    sysread(BUF_SIZE, @buf)
   end
 
   def ungetc(substr)
     raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String)
     if @buf.empty?
-      @buf = substr.dup
+      @buf.replace(substr)
     else
-      @buf = substr + @buf
+      @buf[0,0] = substr
     end
     nil
   end
@@ -207,9 +207,8 @@ class IO
       end
 
       if length
-        consume = (length <= @buf.size) ? length : @buf.size
-        array.push @buf[0, consume]
-        @buf = @buf[consume, @buf.size - consume]
+        consume = (length <= @buf.bytesize) ? length : @buf.bytesize
+        array.push IO._bufread(@buf, consume)
         length -= consume
         break if length == 0
       else
@@ -226,12 +225,12 @@ class IO
     end
   end
 
-  def readline(arg = $/, limit = nil)
+  def readline(arg = "\n", limit = nil)
     case arg
     when String
       rs = arg
     when Fixnum
-      rs = $/
+      rs = "\n"
       limit = arg
     else
       raise ArgumentError
@@ -242,7 +241,7 @@ class IO
     end
 
     if rs == ""
-      rs = $/ + $/
+      rs = "\n\n"
     end
 
     array = []
@@ -256,12 +255,12 @@ class IO
 
       if limit && limit <= @buf.size
         array.push @buf[0, limit]
-        @buf = @buf[limit, @buf.size - limit]
+        @buf[0, limit] = ""
         break
       elsif idx = @buf.index(rs)
         len = idx + rs.size
         array.push @buf[0, len]
-        @buf = @buf[len, @buf.size - len]
+        @buf[0, len] = ""
         break
       else
         array.push @buf
@@ -284,21 +283,23 @@ class IO
 
   def readchar
     _read_buf
-    c = @buf[0]
-    @buf = @buf[1, @buf.size]
-    c
+    _readchar(@buf)
   end
 
   def getc
     begin
       readchar
     rescue EOFError
+      c = @buf[0]
+      @buf[0,1]="" if c
       nil
     end
   end
 
   # 15.2.20.5.3
   def each(&block)
+    return to_enum unless block
+
     while line = self.gets
       block.call(line)
     end
@@ -307,6 +308,8 @@ class IO
 
   # 15.2.20.5.4
   def each_byte(&block)
+    return to_enum(:each_byte) unless block
+
     while char = self.getc
       block.call(char)
     end
@@ -364,25 +367,3 @@ STDERR = IO.open(2, "w")
 $stdin  = STDIN
 $stdout = STDOUT
 $stderr = STDERR
-
-module Kernel
-  def print(*args)
-    $stdout.print(*args)
-  end
-
-  def puts(*args)
-    $stdout.puts(*args)
-  end
-
-  def printf(*args)
-    $stdout.printf(*args)
-  end
-
-  def gets(*args)
-    $stdin.gets(*args)
-  end
-
-  def getc(*args)
-    $stdin.getc(*args)
-  end
-end
index 373b76f..9cb3b56 100644 (file)
@@ -12,4 +12,20 @@ module Kernel
       File.open(file, *rest, &block)
     end
   end
+
+  def print(*args)
+    $stdout.print(*args)
+  end
+
+  def puts(*args)
+    $stdout.puts(*args)
+  end
+
+  def printf(*args)
+    $stdout.printf(*args)
+  end
+
+  def gets(*args)
+    $stdin.gets(*args)
+  end
 end
diff --git a/third-party/mruby/mrbgems/mruby-io/run_test.rb b/third-party/mruby/mrbgems/mruby-io/run_test.rb
deleted file mode 100644 (file)
index 83d8029..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env ruby
-#
-# mrbgems test runner
-#
-
-if __FILE__ == $0
-  repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
-  build_args = ARGV
-
-  Dir.mkdir 'tmp'  unless File.exist?('tmp')
-  unless File.exist?(dir)
-    system "git clone #{repository} #{dir}"
-  end
-
-  exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
-end
-
-MRuby::Build.new do |conf|
-  toolchain :gcc
-  conf.gembox 'default'
-
-  conf.gem :git => 'https://github.com/iij/mruby-env.git'
-  conf.enable_test
-
-  conf.gem File.expand_path(File.dirname(__FILE__))
-end
index c006634..6c99300 100644 (file)
@@ -7,12 +7,7 @@
 #include "mruby/data.h"
 #include "mruby/string.h"
 #include "mruby/ext/io.h"
-
-#if MRUBY_RELEASE_NO < 10000
-#include "error.h"
-#else
 #include "mruby/error.h"
-#endif
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -53,6 +48,7 @@
 #if defined(_WIN32) || defined(_WIN64)
   #define PATH_SEPARATOR ";"
   #define FILE_ALT_SEPARATOR "\\"
+  #define VOLUME_SEPARATOR ":"
 #else
   #define PATH_SEPARATOR ":"
 #endif
 #define LOCK_UN 8
 #endif
 
-#define STAT(p, s)        stat(p, s)
+#ifndef _WIN32
+typedef struct stat         mrb_stat;
+# define mrb_stat(path, sb) stat(path, sb)
+# define mrb_fstat(fd, sb)  fstat(fd, sb)
+#else
+typedef struct __stat64     mrb_stat;
+# define mrb_stat(path, sb) _stat64(path, sb)
+# define mrb_fstat(fd, sb)  _fstat64(fd, sb)
+#endif
 
 #ifdef _WIN32
 static int
@@ -85,7 +89,7 @@ flock(int fd, int operation) {
 }
 #endif
 
-mrb_value
+static mrb_value
 mrb_file_s_umask(mrb_state *mrb, mrb_value klass)
 {
 #if defined(_WIN32) || defined(_WIN64)
@@ -116,7 +120,7 @@ mrb_file_s_unlink(mrb_state *mrb, mrb_value obj)
   for (i = 0; i < argc; i++) {
     const char *utf8_path;
     pathv = mrb_ensure_string_type(mrb, argv[i]);
-    utf8_path = mrb_string_value_cstr(mrb, &pathv);
+    utf8_path = RSTRING_CSTR(mrb, pathv);
     path = mrb_locale_from_utf8(utf8_path, -1);
     if (UNLINK(path) < 0) {
       mrb_locale_free(path);
@@ -134,8 +138,8 @@ mrb_file_s_rename(mrb_state *mrb, mrb_value obj)
   char *src, *dst;
 
   mrb_get_args(mrb, "SS", &from, &to);
-  src = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &from), -1);
-  dst = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &to), -1);
+  src = mrb_locale_from_utf8(RSTRING_CSTR(mrb, from), -1);
+  dst = mrb_locale_from_utf8(RSTRING_CSTR(mrb, to), -1);
   if (rename(src, dst) < 0) {
 #if defined(_WIN32) || defined(_WIN64)
     if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) {
@@ -146,7 +150,8 @@ mrb_file_s_rename(mrb_state *mrb, mrb_value obj)
 #endif
     mrb_locale_free(src);
     mrb_locale_free(dst);
-    mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to)));
+    mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "(%v, %v)", from, to)));
+    return mrb_fixnum_value(-1); /* not reached */
   }
   mrb_locale_free(src);
   mrb_locale_free(dst);
@@ -159,12 +164,12 @@ mrb_file_dirname(mrb_state *mrb, mrb_value klass)
 #if defined(_WIN32) || defined(_WIN64)
   char dname[_MAX_DIR], vname[_MAX_DRIVE];
   char buffer[_MAX_DRIVE + _MAX_DIR];
+  const char *utf8_path;
   char *path;
   size_t ridx;
-  mrb_value s;
-  mrb_get_args(mrb, "S", &s);
-  path = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, s), -1);
-  _splitpath((const char*)path, vname, dname, NULL, NULL);
+  mrb_get_args(mrb, "z", &utf8_path);
+  path = mrb_locale_from_utf8(utf8_path, -1);
+  _splitpath(path, vname, dname, NULL, NULL);
   snprintf(buffer, _MAX_DRIVE + _MAX_DIR, "%s%s", vname, dname);
   mrb_locale_free(path);
   ridx = strlen(buffer);
@@ -248,18 +253,19 @@ mrb_file_realpath(mrb_state *mrb, mrb_value klass)
     s = mrb_str_append(mrb, s, pathname);
     pathname = s;
   }
-  cpath = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, pathname), -1);
+  cpath = mrb_locale_from_utf8(RSTRING_CSTR(mrb, pathname), -1);
   result = mrb_str_buf_new(mrb, PATH_MAX);
   if (realpath(cpath, RSTRING_PTR(result)) == NULL) {
     mrb_locale_free(cpath);
     mrb_sys_fail(mrb, cpath);
+    return result;              /* not reached */
   }
   mrb_locale_free(cpath);
   mrb_str_resize(mrb, result, strlen(RSTRING_PTR(result)));
   return result;
 }
 
-mrb_value
+static mrb_value
 mrb_file__getwd(mrb_state *mrb, mrb_value klass)
 {
   mrb_value path;
@@ -274,12 +280,59 @@ mrb_file__getwd(mrb_state *mrb, mrb_value klass)
   return path;
 }
 
+#ifdef _WIN32
+#define IS_FILESEP(x) (x == (*(char*)(FILE_SEPARATOR)) || x == (*(char*)(FILE_ALT_SEPARATOR)))
+#define IS_VOLSEP(x) (x == (*(char*)(VOLUME_SEPARATOR)))
+#define IS_DEVICEID(x) (x == '.' || x == '?')
+#define CHECK_UNCDEV_PATH (IS_FILESEP(path[0]) && IS_FILESEP(path[1]))
+
+static int 
+is_absolute_traditional_path(const char *path, size_t len)
+{
+  if (len < 3) return 0;
+  return (ISALPHA(path[0]) && IS_VOLSEP(path[1]) && IS_FILESEP(path[2]));
+}
+
+static int 
+is_aboslute_unc_path(const char *path, size_t len) {
+  if (len < 2) return 0;
+  return (CHECK_UNCDEV_PATH && !IS_DEVICEID(path[2]));
+}
+
+static int 
+is_absolute_device_path(const char *path, size_t len) {
+  if (len < 4) return 0;
+  return (CHECK_UNCDEV_PATH && IS_DEVICEID(path[2]) && IS_FILESEP(path[3]));
+}
+
 static int
 mrb_file_is_absolute_path(const char *path)
 {
-  return (path[0] == '/');
+  size_t len = strlen(path);
+  if (IS_FILESEP(path[0])) return 1;
+  if (len > 0)
+    return (
+      is_absolute_traditional_path(path, len) || 
+      is_aboslute_unc_path(path, len) || 
+      is_absolute_device_path(path, len)
+      );
+  else
+    return 0;
 }
 
+#undef IS_FILESEP
+#undef IS_VOLSEP
+#undef IS_DEVICEID
+#undef CHECK_UNCDEV_PATH
+
+#else
+static int
+mrb_file_is_absolute_path(const char *path)
+{
+  return (path[0] == *(char*)(FILE_SEPARATOR));
+}
+#endif
+
 static mrb_value
 mrb_file__gethome(mrb_state *mrb, mrb_value klass)
 {
@@ -300,21 +353,21 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass)
       mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home");
     }
   } else {
-    const char *cuser = mrb_str_to_cstr(mrb, username);
+    const char *cuser = RSTRING_CSTR(mrb, username);
     struct passwd *pwd = getpwnam(cuser);
     if (pwd == NULL) {
       return mrb_nil_value();
     }
     home = pwd->pw_dir;
     if (!mrb_file_is_absolute_path(home)) {
-      mrb_raisef(mrb, E_ARGUMENT_ERROR, "non-absolute home of ~%S", username);
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "non-absolute home of ~%v", username);
     }
   }
   home = mrb_locale_from_utf8(home, -1);
   path = mrb_str_new_cstr(mrb, home);
   mrb_locale_free(home);
   return path;
-#else
+#else  /* _WIN32 */
   argc = mrb_get_argc(mrb);
   if (argc == 0) {
     home = getenv("USERPROFILE");
@@ -342,13 +395,13 @@ mrb_file_mtime(mrb_state *mrb, mrb_value self)
   int fd;
 
   obj = mrb_obj_value(mrb_class_get(mrb, "Time"));
-  fd = (int)mrb_fixnum(mrb_io_fileno(mrb, self));
+  fd = mrb_io_fileno(mrb, self);
   if (fstat(fd, &st) == -1)
     return mrb_false_value();
   return mrb_funcall(mrb, obj, "at", 1, mrb_fixnum_value(st.st_mtime));
 }
 
-mrb_value
+static mrb_value
 mrb_file_flock(mrb_state *mrb, mrb_value self)
 {
 #if defined(sun)
@@ -358,7 +411,7 @@ mrb_file_flock(mrb_state *mrb, mrb_value self)
   int fd;
 
   mrb_get_args(mrb, "i", &operation);
-  fd = (int)mrb_fixnum(mrb_io_fileno(mrb, self));
+  fd = mrb_io_fileno(mrb, self);
 
   while (flock(fd, (int)operation) == -1) {
     switch (errno) {
@@ -383,6 +436,74 @@ mrb_file_flock(mrb_state *mrb, mrb_value self)
 }
 
 static mrb_value
+mrb_file_size(mrb_state *mrb, mrb_value self)
+{
+  mrb_stat st;
+  int fd;
+
+  fd = mrb_io_fileno(mrb, self);
+  if (mrb_fstat(fd, &st) == -1) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "fstat failed");
+  }
+
+  if (st.st_size > MRB_INT_MAX) {
+#ifdef MRB_WITHOUT_FLOAT
+    mrb_raise(mrb, E_RUNTIME_ERROR, "File#size too large for MRB_WITHOUT_FLOAT");
+#else
+    return mrb_float_value(mrb, (mrb_float)st.st_size);
+#endif
+  }
+
+  return mrb_fixnum_value((mrb_int)st.st_size);
+}
+
+static int
+mrb_ftruncate(int fd, mrb_int length)
+{
+#ifndef _WIN32
+  return ftruncate(fd, (off_t)length);
+#else
+  HANDLE file;
+  __int64 cur;
+
+  file = (HANDLE)_get_osfhandle(fd);
+  if (file == INVALID_HANDLE_VALUE) {
+    return -1;
+  }
+
+  cur = _lseeki64(fd, 0, SEEK_CUR);
+  if (cur == -1) return -1;
+
+  if (_lseeki64(fd, (__int64)length, SEEK_SET) == -1) return -1;
+
+  if (!SetEndOfFile(file)) {
+    errno = EINVAL; /* TODO: GetLastError to errno */
+    return -1;
+  }
+
+  if (_lseeki64(fd, cur, SEEK_SET) == -1) return -1;
+
+  return 0;
+#endif /* _WIN32 */
+}
+
+static mrb_value
+mrb_file_truncate(mrb_state *mrb, mrb_value self)
+{
+  int fd;
+  mrb_int length;
+  mrb_value lenv = mrb_get_arg1(mrb);
+
+  fd = mrb_io_fileno(mrb, self);
+  length = mrb_int(mrb, lenv);
+  if (mrb_ftruncate(fd, length) != 0) {
+    mrb_raise(mrb, E_IO_ERROR, "ftruncate failed");
+  }
+
+  return mrb_fixnum_value(0);
+}
+
+static mrb_value
 mrb_file_s_symlink(mrb_state *mrb, mrb_value klass)
 {
 #if defined(_WIN32) || defined(_WIN64)
@@ -393,13 +514,12 @@ mrb_file_s_symlink(mrb_state *mrb, mrb_value klass)
   int ai = mrb_gc_arena_save(mrb);
 
   mrb_get_args(mrb, "SS", &from, &to);
-  src = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, from), -1);
-  dst = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, to), -1);
-
+  src = mrb_locale_from_utf8(RSTRING_CSTR(mrb, from), -1);
+  dst = mrb_locale_from_utf8(RSTRING_CSTR(mrb, to), -1);
   if (symlink(src, dst) == -1) {
     mrb_locale_free(src);
     mrb_locale_free(dst);
-    mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to)));
+    mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "(%v, %v)", from, to)));
   }
   mrb_locale_free(src);
   mrb_locale_free(dst);
@@ -417,16 +537,16 @@ mrb_file_s_chmod(mrb_state *mrb, mrb_value klass) {
 
   mrb_get_args(mrb, "i*", &mode, &filenames, &argc);
   for (i = 0; i < argc; i++) {
-    const char *utf8_path = mrb_str_to_cstr(mrb, filenames[i]);
+    const char *utf8_path = RSTRING_CSTR(mrb, filenames[i]);
     char *path = mrb_locale_from_utf8(utf8_path, -1);
     if (CHMOD(path, mode) == -1) {
       mrb_locale_free(path);
       mrb_sys_fail(mrb, utf8_path);
     }
     mrb_locale_free(path);
+    mrb_gc_arena_restore(mrb, ai);
   }
 
-  mrb_gc_arena_restore(mrb, ai);
   return mrb_fixnum_value(argc);
 }
 
@@ -473,7 +593,7 @@ mrb_init_file(mrb_state *mrb)
   io   = mrb_class_get(mrb, "IO");
   file = mrb_define_class(mrb, "File", io);
   MRB_SET_INSTANCE_TT(file, MRB_TT_DATA);
-  mrb_define_class_method(mrb, file, "umask",  mrb_file_s_umask, MRB_ARGS_REQ(1));
+  mrb_define_class_method(mrb, file, "umask",  mrb_file_s_umask, MRB_ARGS_OPT(1));
   mrb_define_class_method(mrb, file, "delete", mrb_file_s_unlink, MRB_ARGS_ANY());
   mrb_define_class_method(mrb, file, "unlink", mrb_file_s_unlink, MRB_ARGS_ANY());
   mrb_define_class_method(mrb, file, "rename", mrb_file_s_rename, MRB_ARGS_REQ(2));
@@ -489,6 +609,8 @@ mrb_init_file(mrb_state *mrb)
 
   mrb_define_method(mrb, file, "flock", mrb_file_flock, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, file, "mtime", mrb_file_mtime, MRB_ARGS_NONE());
+  mrb_define_method(mrb, file, "size", mrb_file_size, MRB_ARGS_NONE());
+  mrb_define_method(mrb, file, "truncate", mrb_file_truncate, MRB_ARGS_REQ(1));
 
   cnst = mrb_define_module_under(mrb, file, "Constants");
   mrb_define_const(mrb, cnst, "LOCK_SH", mrb_fixnum_value(LOCK_SH));
@@ -504,4 +626,22 @@ mrb_init_file(mrb_state *mrb)
 #endif
   mrb_define_const(mrb, cnst, "NULL", mrb_str_new_cstr(mrb, NULL_FILE));
 
+  mrb_define_const(mrb, cnst, "RDONLY", mrb_fixnum_value(MRB_O_RDONLY));
+  mrb_define_const(mrb, cnst, "WRONLY", mrb_fixnum_value(MRB_O_WRONLY));
+  mrb_define_const(mrb, cnst, "RDWR", mrb_fixnum_value(MRB_O_RDWR));
+  mrb_define_const(mrb, cnst, "APPEND", mrb_fixnum_value(MRB_O_APPEND));
+  mrb_define_const(mrb, cnst, "CREAT", mrb_fixnum_value(MRB_O_CREAT));
+  mrb_define_const(mrb, cnst, "EXCL", mrb_fixnum_value(MRB_O_EXCL));
+  mrb_define_const(mrb, cnst, "TRUNC", mrb_fixnum_value(MRB_O_TRUNC));
+  mrb_define_const(mrb, cnst, "NONBLOCK", mrb_fixnum_value(MRB_O_NONBLOCK));
+  mrb_define_const(mrb, cnst, "NOCTTY", mrb_fixnum_value(MRB_O_NOCTTY));
+  mrb_define_const(mrb, cnst, "BINARY", mrb_fixnum_value(MRB_O_BINARY));
+  mrb_define_const(mrb, cnst, "SHARE_DELETE", mrb_fixnum_value(MRB_O_SHARE_DELETE));
+  mrb_define_const(mrb, cnst, "SYNC", mrb_fixnum_value(MRB_O_SYNC));
+  mrb_define_const(mrb, cnst, "DSYNC", mrb_fixnum_value(MRB_O_DSYNC));
+  mrb_define_const(mrb, cnst, "RSYNC", mrb_fixnum_value(MRB_O_RSYNC));
+  mrb_define_const(mrb, cnst, "NOFOLLOW", mrb_fixnum_value(MRB_O_NOFOLLOW));
+  mrb_define_const(mrb, cnst, "NOATIME", mrb_fixnum_value(MRB_O_NOATIME));
+  mrb_define_const(mrb, cnst, "DIRECT", mrb_fixnum_value(MRB_O_DIRECT));
+  mrb_define_const(mrb, cnst, "TMPFILE", mrb_fixnum_value(MRB_O_TMPFILE));
 }
index e429b06..b7a28f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
-** file.c - File class
+** file_test.c - FileTest class
 */
 
 #include "mruby.h"
@@ -7,12 +7,7 @@
 #include "mruby/data.h"
 #include "mruby/string.h"
 #include "mruby/ext/io.h"
-
-#if MRUBY_RELEASE_NO < 10000
-#include "error.h"
-#else
 #include "mruby/error.h"
-#endif
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -33,7 +28,6 @@
 #include <fcntl.h>
 
 #include <errno.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -42,16 +36,9 @@ extern struct mrb_data_type mrb_io_type;
 static int
 mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
 {
-  mrb_value tmp;
-  mrb_value io_klass, str_klass;
-
-  io_klass  = mrb_obj_value(mrb_class_get(mrb, "IO"));
-  str_klass = mrb_obj_value(mrb_class_get(mrb, "String"));
-
-  tmp = mrb_funcall(mrb, obj, "is_a?", 1, io_klass);
-  if (mrb_test(tmp)) {
+  if (mrb_obj_is_kind_of(mrb, obj, mrb_class_get(mrb, "IO"))) {
     struct mrb_io *fptr;
-    fptr = (struct mrb_io *)mrb_get_datatype(mrb, obj, &mrb_io_type);
+    fptr = (struct mrb_io *)mrb_data_get_ptr(mrb, obj, &mrb_io_type);
 
     if (fptr && fptr->fd >= 0) {
       return fstat(fptr->fd, st);
@@ -60,10 +47,8 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
     mrb_raise(mrb, E_IO_ERROR, "closed stream");
     return -1;
   }
-
-  tmp = mrb_funcall(mrb, obj, "is_a?", 1, str_klass);
-  if (mrb_test(tmp)) {
-    char *path = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, obj), -1);
+  else {
+    char *path = mrb_locale_from_utf8(RSTRING_CSTR(mrb, obj), -1);
     int ret;
     if (do_lstat) {
       ret = LSTAT(path, st);
@@ -73,8 +58,6 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
     mrb_locale_free(path);
     return ret;
   }
-
-  return -1;
 }
 
 static int
@@ -102,7 +85,7 @@ mrb_lstat(mrb_state *mrb, mrb_value obj, struct stat *st)
  *    File.directory?(".")
  */
 
-mrb_value
+static mrb_value
 mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
 {
 #ifndef S_ISDIR
@@ -110,9 +93,7 @@ mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
 #endif
 
   struct stat st;
-  mrb_value obj;
-
-  mrb_get_args(mrb, "o", &obj);
+  mrb_value obj = mrb_get_arg1(mrb);
 
   if (mrb_stat(mrb, obj, &st) < 0)
     return mrb_false_value();
@@ -129,7 +110,7 @@ mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
  * Returns <code>true</code> if the named file is a pipe.
  */
 
-mrb_value
+static mrb_value
 mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
 {
 #if defined(_WIN32) || defined(_WIN64)
@@ -141,9 +122,7 @@ mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
 #  endif
 
   struct stat st;
-  mrb_value obj;
-
-  mrb_get_args(mrb, "o", &obj);
+  mrb_value obj = mrb_get_arg1(mrb);
 
   if (mrb_stat(mrb, obj, &st) < 0)
     return mrb_false_value();
@@ -162,7 +141,7 @@ mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
  * Returns <code>true</code> if the named file is a symbolic link.
  */
 
-mrb_value
+static mrb_value
 mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
 {
 #if defined(_WIN32) || defined(_WIN64)
@@ -184,9 +163,7 @@ mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
 
 #ifdef S_ISLNK
   struct stat st;
-  mrb_value obj;
-
-  mrb_get_args(mrb, "o", &obj);
+  mrb_value obj = mrb_get_arg1(mrb);
 
   if (mrb_lstat(mrb, obj, &st) == -1)
     return mrb_false_value();
@@ -205,7 +182,7 @@ mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
  * Returns <code>true</code> if the named file is a socket.
  */
 
-mrb_value
+static mrb_value
 mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
 {
 #if defined(_WIN32) || defined(_WIN64)
@@ -227,9 +204,7 @@ mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
 
 #ifdef S_ISSOCK
   struct stat st;
-  mrb_value obj;
-
-  mrb_get_args(mrb, "o", &obj);
+  mrb_value obj = mrb_get_arg1(mrb);
 
   if (mrb_stat(mrb, obj, &st) < 0)
     return mrb_false_value();
@@ -249,13 +224,12 @@ mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
  * Return <code>true</code> if the named file exists.
  */
 
-mrb_value
+static mrb_value
 mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
 {
   struct stat st;
-  mrb_value obj;
+  mrb_value obj = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &obj);
   if (mrb_stat(mrb, obj, &st) < 0)
     return mrb_false_value();
 
@@ -270,7 +244,7 @@ mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
  * regular file.
  */
 
-mrb_value
+static mrb_value
 mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
 {
 #ifndef S_ISREG
@@ -278,9 +252,7 @@ mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
 #endif
 
   struct stat st;
-  mrb_value obj;
-
-  mrb_get_args(mrb, "o", &obj);
+  mrb_value obj = mrb_get_arg1(mrb);
 
   if (mrb_stat(mrb, obj, &st) < 0)
     return mrb_false_value();
@@ -298,13 +270,11 @@ mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
  * a zero size.
  */
 
-mrb_value
+static mrb_value
 mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
 {
   struct stat st;
-  mrb_value obj;
-
-  mrb_get_args(mrb, "o", &obj);
+  mrb_value obj = mrb_get_arg1(mrb);
 
   if (mrb_stat(mrb, obj, &st) < 0)
     return mrb_false_value();
@@ -323,13 +293,11 @@ mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
  * _file_name_ can be an IO object.
  */
 
-mrb_value
+static mrb_value
 mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
 {
   struct stat st;
-  mrb_value obj;
-
-  mrb_get_args(mrb, "o", &obj);
+  mrb_value obj = mrb_get_arg1(mrb);
 
   if (mrb_stat(mrb, obj, &st) < 0)
     mrb_sys_fail(mrb, "mrb_stat");
@@ -345,13 +313,11 @@ mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
  * file otherwise.
  */
 
-mrb_value
+static mrb_value
 mrb_filetest_s_size_p(mrb_state *mrb, mrb_value klass)
 {
   struct stat st;
-  mrb_value obj;
-
-  mrb_get_args(mrb, "o", &obj);
+  mrb_value obj = mrb_get_arg1(mrb);
 
   if (mrb_stat(mrb, obj, &st) < 0)
     return mrb_nil_value();
index e5b83e9..505ceb2 100644 (file)
 #include "mruby/string.h"
 #include "mruby/variable.h"
 #include "mruby/ext/io.h"
-
-#if MRUBY_RELEASE_NO < 10000
-#include "error.h"
-#else
 #include "mruby/error.h"
-#endif
 
 #include <sys/types.h>
 #include <sys/stat.h>
   typedef long ftime_t;
   typedef long fsuseconds_t;
   typedef int fmode_t;
+  typedef int mrb_io_read_write_size;
+
+  #ifndef O_TMPFILE
+    #define O_TMPFILE O_TEMPORARY
+  #endif
 
 #else
   #include <sys/wait.h>
+  #include <sys/time.h>
   #include <unistd.h>
   typedef size_t fsize_t;
   typedef time_t ftime_t;
   typedef suseconds_t fsuseconds_t;
   typedef mode_t fmode_t;
+  typedef ssize_t mrb_io_read_write_size;
 #endif
 
 #ifdef _MSC_VER
@@ -53,9 +55,14 @@ typedef mrb_int pid_t;
 #include <fcntl.h>
 
 #include <errno.h>
-#include <stdio.h>
 #include <string.h>
 
+#define OPEN_ACCESS_MODE_FLAGS (O_RDONLY | O_WRONLY | O_RDWR)
+#define OPEN_RDONLY_P(f)       ((mrb_bool)(((f) & OPEN_ACCESS_MODE_FLAGS) == O_RDONLY))
+#define OPEN_WRONLY_P(f)       ((mrb_bool)(((f) & OPEN_ACCESS_MODE_FLAGS) == O_WRONLY))
+#define OPEN_RDWR_P(f)         ((mrb_bool)(((f) & OPEN_ACCESS_MODE_FLAGS) == O_RDWR))
+#define OPEN_READABLE_P(f)     ((mrb_bool)(OPEN_RDONLY_P(f) || OPEN_RDWR_P(f)))
+#define OPEN_WRITABLE_P(f)     ((mrb_bool)(OPEN_WRONLY_P(f) || OPEN_RDWR_P(f)))
 
 static void mrb_io_free(mrb_state *mrb, void *ptr);
 struct mrb_data_type mrb_io_type = { "IO", mrb_io_free };
@@ -63,23 +70,15 @@ struct mrb_data_type mrb_io_type = { "IO", mrb_io_free };
 
 static struct mrb_io *io_get_open_fptr(mrb_state *mrb, mrb_value self);
 static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr);
-static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags);
+static int mrb_io_mode_to_flags(mrb_state *mrb, mrb_value mode);
 static void fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet);
 
-#if MRUBY_RELEASE_NO < 10000
-static struct RClass *
-mrb_module_get(mrb_state *mrb, const char *name)
-{
-  return mrb_class_get(mrb, name);
-}
-#endif
-
 static struct mrb_io *
 io_get_open_fptr(mrb_state *mrb, mrb_value self)
 {
   struct mrb_io *fptr;
 
-  fptr = (struct mrb_io *)mrb_get_datatype(mrb, self, &mrb_io_type);
+  fptr = (struct mrb_io *)mrb_data_get_ptr(mrb, self, &mrb_io_type);
   if (fptr == NULL) {
     mrb_raise(mrb, E_IO_ERROR, "uninitialized stream.");
   }
@@ -113,35 +112,38 @@ io_set_process_status(mrb_state *mrb, pid_t pid, int status)
 static int
 mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode)
 {
-  int flags = 0;
+  int flags;
   const char *m = mode;
 
   switch (*m++) {
     case 'r':
-      flags |= FMODE_READABLE;
+      flags = O_RDONLY;
       break;
     case 'w':
-      flags |= FMODE_WRITABLE | FMODE_CREATE | FMODE_TRUNC;
+      flags = O_WRONLY | O_CREAT | O_TRUNC;
       break;
     case 'a':
-      flags |= FMODE_WRITABLE | FMODE_APPEND | FMODE_CREATE;
+      flags = O_WRONLY | O_CREAT | O_APPEND;
       break;
     default:
-      mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %S", mrb_str_new_cstr(mrb, mode));
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %s", mode);
+      flags = 0; /* not reached */
   }
 
   while (*m) {
     switch (*m++) {
       case 'b':
-        flags |= FMODE_BINMODE;
+#ifdef O_BINARY
+        flags |= O_BINARY;
+#endif
         break;
       case '+':
-        flags |= FMODE_READWRITE;
+        flags = (flags & ~OPEN_ACCESS_MODE_FLAGS) | O_RDWR;
         break;
       case ':':
         /* XXX: PASSTHROUGH*/
       default:
-        mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %S", mrb_str_new_cstr(mrb, mode));
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %s", mode);
     }
   }
 
@@ -149,38 +151,72 @@ mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode)
 }
 
 static int
-mrb_io_flags_to_modenum(mrb_state *mrb, int flags)
+mrb_io_mode_to_flags(mrb_state *mrb, mrb_value mode)
 {
-  int modenum = 0;
-
-  switch(flags & (FMODE_READABLE|FMODE_WRITABLE|FMODE_READWRITE)) {
-    case FMODE_READABLE:
-      modenum = O_RDONLY;
-      break;
-    case FMODE_WRITABLE:
-      modenum = O_WRONLY;
-      break;
-    case FMODE_READWRITE:
-      modenum = O_RDWR;
-      break;
-  }
-
-  if (flags & FMODE_APPEND) {
-    modenum |= O_APPEND;
-  }
-  if (flags & FMODE_TRUNC) {
-    modenum |= O_TRUNC;
+  if (mrb_nil_p(mode)) {
+    return mrb_io_modestr_to_flags(mrb, "r");
   }
-  if (flags & FMODE_CREATE) {
-    modenum |= O_CREAT;
+  else if (mrb_string_p(mode)) {
+    return mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));
   }
+  else {
+    int flags = 0;
+    mrb_int flags0 = mrb_int(mrb, mode);
+
+    switch (flags0 & MRB_O_ACCMODE) {
+      case MRB_O_RDONLY:
+        flags |= O_RDONLY;
+        break;
+      case MRB_O_WRONLY:
+        flags |= O_WRONLY;
+        break;
+      case MRB_O_RDWR:
+        flags |= O_RDWR;
+        break;
+      default:
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %v", mode);
+    }
+
+    if (flags0 & MRB_O_APPEND)        flags |= O_APPEND;
+    if (flags0 & MRB_O_CREAT)         flags |= O_CREAT;
+    if (flags0 & MRB_O_EXCL)          flags |= O_EXCL;
+    if (flags0 & MRB_O_TRUNC)         flags |= O_TRUNC;
+#ifdef O_NONBLOCK
+    if (flags0 & MRB_O_NONBLOCK)      flags |= O_NONBLOCK;
+#endif
+#ifdef O_NOCTTY
+    if (flags0 & MRB_O_NOCTTY)        flags |= O_NOCTTY;
+#endif
 #ifdef O_BINARY
-  if (flags & FMODE_BINMODE) {
-    modenum |= O_BINARY;
-  }
+    if (flags0 & MRB_O_BINARY)        flags |= O_BINARY;
+#endif
+#ifdef O_SHARE_DELETE
+    if (flags0 & MRB_O_SHARE_DELETE)  flags |= O_SHARE_DELETE;
+#endif
+#ifdef O_SYNC
+    if (flags0 & MRB_O_SYNC)          flags |= O_SYNC;
+#endif
+#ifdef O_DSYNC
+    if (flags0 & MRB_O_DSYNC)         flags |= O_DSYNC;
+#endif
+#ifdef O_RSYNC
+    if (flags0 & MRB_O_RSYNC)         flags |= O_RSYNC;
+#endif
+#ifdef O_NOFOLLOW
+    if (flags0 & MRB_O_NOFOLLOW)      flags |= O_NOFOLLOW;
+#endif
+#ifdef O_NOATIME
+    if (flags0 & MRB_O_NOATIME)       flags |= O_NOATIME;
+#endif
+#ifdef O_DIRECT
+    if (flags0 & MRB_O_DIRECT)        flags |= O_DIRECT;
+#endif
+#ifdef O_TMPFILE
+    if (flags0 & MRB_O_TMPFILE)       flags |= O_TMPFILE;
 #endif
 
-  return modenum;
+    return flags;
+  }
 }
 
 static void
@@ -191,8 +227,7 @@ mrb_fd_cloexec(mrb_state *mrb, int fd)
 
   flags = fcntl(fd, F_GETFD);
   if (flags == -1) {
-    mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%S, F_GETFD) failed: %S",
-      mrb_fixnum_value(fd), mrb_fixnum_value(errno));
+    mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%d, F_GETFD) failed: %d", fd, errno);
   }
   if (fd <= 2) {
     flags2 = flags & ~FD_CLOEXEC; /* Clear CLOEXEC for standard file descriptors: 0, 1, 2. */
@@ -202,8 +237,7 @@ mrb_fd_cloexec(mrb_state *mrb, int fd)
   }
   if (flags != flags2) {
     if (fcntl(fd, F_SETFD, flags2) == -1) {
-      mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%S, F_SETFD, %S) failed: %S",
-        mrb_fixnum_value(fd), mrb_fixnum_value(flags2), mrb_fixnum_value(errno));
+      mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%d, F_SETFD, %d) failed: %d", fd, flags2, errno);
     }
   }
 #endif
@@ -286,16 +320,17 @@ mrb_io_alloc(mrb_state *mrb)
 #endif
 
 static int
-option_to_fd(mrb_state *mrb, mrb_value obj, const char *key)
+option_to_fd(mrb_state *mrb, mrb_value hash, const char *key)
 {
-  mrb_value opt = mrb_funcall(mrb, obj, "[]", 1, mrb_symbol_value(mrb_intern_static(mrb, key, strlen(key))));
-  if (mrb_nil_p(opt)) {
-    return -1;
-  }
+  mrb_value opt;
+
+  if (!mrb_hash_p(hash)) return -1;
+  opt = mrb_hash_fetch(mrb, hash, mrb_symbol_value(mrb_intern_static(mrb, key, strlen(key))), mrb_nil_value());
+  if (mrb_nil_p(opt)) return -1;
 
   switch (mrb_type(opt)) {
     case MRB_TT_DATA: /* IO */
-      return (int)mrb_fixnum(mrb_io_fileno(mrb, opt));
+      return mrb_io_fileno(mrb, opt);
     case MRB_TT_FIXNUM:
       return (int)mrb_fixnum(opt);
     default:
@@ -306,7 +341,7 @@ option_to_fd(mrb_state *mrb, mrb_value obj, const char *key)
 }
 
 #ifdef _WIN32
-mrb_value
+static mrb_value
 mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
 {
   mrb_value cmd, io;
@@ -331,11 +366,11 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
   ofd[0] = INVALID_HANDLE_VALUE;
   ofd[1] = INVALID_HANDLE_VALUE;
 
-  mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt);
+  mrb_get_args(mrb, "S|oH", &cmd, &mode, &opt);
   io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
 
-  pname = mrb_string_value_cstr(mrb, &cmd);
-  flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));
+  pname = RSTRING_CSTR(mrb, cmd);
+  flags = mrb_io_mode_to_flags(mrb, mode);
 
   doexec = (strcmp("-", pname) != 0);
   opt_in = option_to_fd(mrb, opt, "in");
@@ -346,14 +381,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
   saAttr.bInheritHandle = TRUE;
   saAttr.lpSecurityDescriptor = NULL;
 
-  if (flags & FMODE_READABLE) {
+  if (OPEN_READABLE_P(flags)) {
     if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0)
         || !SetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) {
       mrb_sys_fail(mrb, "pipe");
     }
   }
 
-  if (flags & FMODE_WRITABLE) {
+  if (OPEN_WRITABLE_P(flags)) {
     if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0)
         || !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) {
       mrb_sys_fail(mrb, "pipe");
@@ -367,11 +402,11 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
     si.dwFlags |= STARTF_USESHOWWINDOW;
     si.wShowWindow = SW_HIDE;
     si.dwFlags |= STARTF_USESTDHANDLES;
-    if (flags & FMODE_READABLE) {
+    if (OPEN_READABLE_P(flags)) {
       si.hStdOutput = ofd[1];
       si.hStdError = ofd[1];
     }
-    if (flags & FMODE_WRITABLE) {
+    if (OPEN_WRITABLE_P(flags)) {
       si.hStdInput = ifd[0];
     }
     if (!CreateProcess(
@@ -381,7 +416,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
       CloseHandle(ifd[1]);
       CloseHandle(ofd[0]);
       CloseHandle(ofd[1]);
-      mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd);
+      mrb_raisef(mrb, E_IO_ERROR, "command not found: %v", cmd);
     }
     CloseHandle(pi.hThread);
     CloseHandle(ifd[0]);
@@ -395,8 +430,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
   fptr->fd = _open_osfhandle((intptr_t)ofd[0], 0);
   fptr->fd2 = _open_osfhandle((intptr_t)ifd[1], 0);
   fptr->pid = pid;
-  fptr->readable = ((flags & FMODE_READABLE) != 0);
-  fptr->writable = ((flags & FMODE_WRITABLE) != 0);
+  fptr->readable = OPEN_READABLE_P(flags);
+  fptr->writable = OPEN_WRITABLE_P(flags);
   fptr->sync = 0;
 
   DATA_TYPE(io) = &mrb_io_type;
@@ -404,14 +439,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
   return io;
 }
 #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
-mrb_value
+static mrb_value
 mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
 {
   mrb_raise(mrb, E_NOTIMP_ERROR, "IO#popen is not supported on the platform");
   return mrb_false_value();
 }
 #else
-mrb_value
+static mrb_value
 mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
 {
   mrb_value cmd, io, result;
@@ -427,18 +462,18 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
   int saved_errno;
   int opt_in, opt_out, opt_err;
 
-  mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt);
+  mrb_get_args(mrb, "S|oH", &cmd, &mode, &opt);
   io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
 
-  pname = mrb_string_value_cstr(mrb, &cmd);
-  flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));
+  pname = RSTRING_CSTR(mrb, cmd);
+  flags = mrb_io_mode_to_flags(mrb, mode);
 
   doexec = (strcmp("-", pname) != 0);
   opt_in = option_to_fd(mrb, opt, "in");
   opt_out = option_to_fd(mrb, opt, "out");
   opt_err = option_to_fd(mrb, opt, "err");
 
-  if (flags & FMODE_READABLE) {
+  if (OPEN_READABLE_P(flags)) {
     if (pipe(pr) == -1) {
       mrb_sys_fail(mrb, "pipe");
     }
@@ -446,7 +481,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
     mrb_fd_cloexec(mrb, pr[1]);
   }
 
-  if (flags & FMODE_WRITABLE) {
+  if (OPEN_WRITABLE_P(flags)) {
     if (pipe(pw) == -1) {
       if (pr[0] != -1) close(pr[0]);
       if (pr[1] != -1) close(pr[1]);
@@ -475,14 +510,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
       if (opt_err != -1) {
         dup2(opt_err, 2);
       }
-      if (flags & FMODE_READABLE) {
+      if (OPEN_READABLE_P(flags)) {
         close(pr[0]);
         if (pr[1] != 1) {
           dup2(pr[1], 1);
           close(pr[1]);
         }
       }
-      if (flags & FMODE_WRITABLE) {
+      if (OPEN_WRITABLE_P(flags)) {
         close(pw[1]);
         if (pw[0] != 0) {
           dup2(pw[0], 0);
@@ -494,19 +529,19 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
           close(fd);
         }
         mrb_proc_exec(pname);
-        mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd);
+        mrb_raisef(mrb, E_IO_ERROR, "command not found: %v", cmd);
         _exit(127);
       }
       result = mrb_nil_value();
       break;
 
     default: /* parent */
-      if ((flags & FMODE_READABLE) && (flags & FMODE_WRITABLE)) {
+      if (OPEN_RDWR_P(flags)) {
         close(pr[1]);
         fd = pr[0];
         close(pw[0]);
         write_fd = pw[1];
-      } else if (flags & FMODE_READABLE) {
+      } else if (OPEN_RDONLY_P(flags)) {
         close(pr[1]);
         fd = pr[0];
       } else {
@@ -520,8 +555,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
       fptr->fd = fd;
       fptr->fd2 = write_fd;
       fptr->pid = pid;
-      fptr->readable = ((flags & FMODE_READABLE) != 0);
-      fptr->writable = ((flags & FMODE_WRITABLE) != 0);
+      fptr->readable = OPEN_READABLE_P(flags);
+      fptr->writable = OPEN_WRITABLE_P(flags);
       fptr->sync = 0;
 
       DATA_TYPE(io) = &mrb_io_type;
@@ -531,11 +566,11 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
 
     case -1: /* error */
       saved_errno = errno;
-      if (flags & FMODE_READABLE) {
+      if (OPEN_READABLE_P(flags)) {
         close(pr[0]);
         close(pr[1]);
       }
-      if (flags & FMODE_WRITABLE) {
+      if (OPEN_WRITABLE_P(flags)) {
         close(pw[0]);
         close(pw[1]);
       }
@@ -561,16 +596,15 @@ mrb_dup(mrb_state *mrb, int fd, mrb_bool *failed)
   return new_fd;
 }
 
-mrb_value
+static mrb_value
 mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
 {
-  mrb_value orig;
+  mrb_value orig = mrb_get_arg1(mrb);
   mrb_value buf;
   struct mrb_io *fptr_copy;
   struct mrb_io *fptr_orig;
   mrb_bool failed = TRUE;
 
-  mrb_get_args(mrb, "o", &orig);
   fptr_orig = io_get_open_fptr(mrb, orig);
   fptr_copy = (struct mrb_io *)DATA_PTR(copy);
   if (fptr_orig == fptr_copy) return copy;
@@ -610,7 +644,44 @@ mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
   return copy;
 }
 
-mrb_value
+static void
+check_file_descriptor(mrb_state *mrb, mrb_int fd)
+{
+  struct stat sb;
+  int fdi = (int)fd;
+
+#if MRB_INT_MIN < INT_MIN || MRB_INT_MAX > INT_MAX
+  if (fdi != fd) {
+    goto badfd;
+  }
+#endif
+
+#ifdef _WIN32
+  {
+    DWORD err;
+    int len = sizeof(err);
+
+    if (getsockopt(fdi, SOL_SOCKET, SO_ERROR, (char*)&err, &len) == 0) {
+      return;
+    }
+  }
+
+  if (fdi < 0 || fdi > _getmaxstdio()) {
+    goto badfd;
+  }
+#endif /* _WIN32 */
+
+  if (fstat(fdi, &sb) != 0) {
+    goto badfd;
+  }
+
+  return;
+
+badfd:
+  mrb_sys_fail(mrb, "bad file descriptor");
+}
+
+static mrb_value
 mrb_io_initialize(mrb_state *mrb, mrb_value io)
 {
   struct mrb_io *fptr;
@@ -620,7 +691,8 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
 
   mode = opt = mrb_nil_value();
 
-  mrb_get_args(mrb, "i|So", &fd, &mode, &opt);
+  mrb_get_args(mrb, "i|oo", &fd, &mode, &opt);
+  check_file_descriptor(mrb, fd);
   if (mrb_nil_p(mode)) {
     mode = mrb_str_new_cstr(mrb, "r");
   }
@@ -628,7 +700,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
     opt = mrb_hash_new(mrb);
   }
 
-  flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));
+  flags = mrb_io_mode_to_flags(mrb, mode);
 
   mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));
 
@@ -643,8 +715,8 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
   DATA_PTR(io) = fptr;
 
   fptr->fd = (int)fd;
-  fptr->readable = ((flags & FMODE_READABLE) != 0);
-  fptr->writable = ((flags & FMODE_WRITABLE) != 0);
+  fptr->readable = OPEN_READABLE_P(flags);
+  fptr->writable = OPEN_WRITABLE_P(flags);
   fptr->sync = 0;
   return io;
 }
@@ -712,7 +784,7 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet)
   }
 }
 
-mrb_value
+static mrb_value
 mrb_io_check_readable(mrb_state *mrb, mrb_value self)
 {
   struct mrb_io *fptr = io_get_open_fptr(mrb, self);
@@ -722,7 +794,7 @@ mrb_io_check_readable(mrb_state *mrb, mrb_value self)
   return mrb_nil_value();
 }
 
-mrb_value
+static mrb_value
 mrb_io_isatty(mrb_state *mrb, mrb_value self)
 {
   struct mrb_io *fptr;
@@ -733,7 +805,7 @@ mrb_io_isatty(mrb_state *mrb, mrb_value self)
   return mrb_true_value();
 }
 
-mrb_value
+static mrb_value
 mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
 {
   struct RClass *c = mrb_class_ptr(klass);
@@ -746,7 +818,7 @@ mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
   return mrb_io_initialize(mrb, obj);
 }
 
-mrb_value
+static mrb_value
 mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
 {
   mrb_int fd;
@@ -757,10 +829,9 @@ mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
   return mrb_fixnum_value(0);
 }
 
-int
+static int
 mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mode)
 {
-  mrb_value emsg;
   int fd, retry = FALSE;
   char* fname = mrb_locale_from_utf8(pathname, -1);
 
@@ -783,9 +854,7 @@ reopen:
       }
     }
 
-    emsg = mrb_format(mrb, "open %S", mrb_str_new_cstr(mrb, pathname));
-    mrb_str_modify(mrb, mrb_str_ptr(emsg));
-    mrb_sys_fail(mrb, RSTRING_PTR(emsg));
+    mrb_sys_fail(mrb, RSTRING_CSTR(mrb, mrb_format(mrb, "open %s", pathname)));
   }
   mrb_locale_free(fname);
 
@@ -795,39 +864,55 @@ reopen:
   return fd;
 }
 
-mrb_value
+static mrb_value
 mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
 {
   mrb_value path = mrb_nil_value();
   mrb_value mode = mrb_nil_value();
   mrb_int fd, perm = -1;
   const char *pat;
-  int flags, modenum;
+  int flags;
 
-  mrb_get_args(mrb, "S|Si", &path, &mode, &perm);
-  if (mrb_nil_p(mode)) {
-    mode = mrb_str_new_cstr(mrb, "r");
-  }
+  mrb_get_args(mrb, "S|oi", &path, &mode, &perm);
   if (perm < 0) {
     perm = 0666;
   }
 
-  pat = mrb_string_value_cstr(mrb, &path);
-  flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));
-  modenum = mrb_io_flags_to_modenum(mrb, flags);
-  fd = mrb_cloexec_open(mrb, pat, modenum, perm);
+  pat = RSTRING_CSTR(mrb, path);
+  flags = mrb_io_mode_to_flags(mrb, mode);
+  fd = mrb_cloexec_open(mrb, pat, flags, perm);
   return mrb_fixnum_value(fd);
 }
 
-mrb_value
+static mrb_value mrb_io_sysread_common(mrb_state *mrb,
+    mrb_io_read_write_size (*readfunc)(int, void *, fsize_t, off_t),
+    mrb_value io, mrb_value buf, mrb_int maxlen, off_t offset);
+
+static mrb_io_read_write_size
+mrb_sysread_dummy(int fd, void *buf, fsize_t nbytes, off_t offset)
+{
+  return (mrb_io_read_write_size)read(fd, buf, nbytes);
+}
+
+static mrb_value
 mrb_io_sysread(mrb_state *mrb, mrb_value io)
 {
-  struct mrb_io *fptr;
   mrb_value buf = mrb_nil_value();
   mrb_int maxlen;
-  int ret;
 
   mrb_get_args(mrb, "i|S", &maxlen, &buf);
+
+  return mrb_io_sysread_common(mrb, mrb_sysread_dummy, io, buf, maxlen, 0);
+}
+
+static mrb_value
+mrb_io_sysread_common(mrb_state *mrb,
+    mrb_io_read_write_size (*readfunc)(int, void *, fsize_t, off_t),
+    mrb_value io, mrb_value buf, mrb_int maxlen, off_t offset)
+{
+  struct mrb_io *fptr;
+  int ret;
+
   if (maxlen < 0) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "negative expanding string size");
   }
@@ -841,7 +926,8 @@ mrb_io_sysread(mrb_state *mrb, mrb_value io)
 
   if (RSTRING_LEN(buf) != maxlen) {
     buf = mrb_str_resize(mrb, buf, maxlen);
-  } else {
+  }
+  else {
     mrb_str_modify(mrb, RSTRING(buf));
   }
 
@@ -849,29 +935,20 @@ mrb_io_sysread(mrb_state *mrb, mrb_value io)
   if (!fptr->readable) {
     mrb_raise(mrb, E_IO_ERROR, "not opened for reading");
   }
-  ret = read(fptr->fd, RSTRING_PTR(buf), (fsize_t)maxlen);
-  switch (ret) {
-    case 0: /* EOF */
-      if (maxlen == 0) {
-        buf = mrb_str_new_cstr(mrb, "");
-      } else {
-        mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File");
-      }
-      break;
-    case -1: /* Error */
-      mrb_sys_fail(mrb, "sysread failed");
-      break;
-    default:
-      if (RSTRING_LEN(buf) != ret) {
-        buf = mrb_str_resize(mrb, buf, ret);
-      }
-      break;
+  ret = readfunc(fptr->fd, RSTRING_PTR(buf), (fsize_t)maxlen, offset);
+  if (ret < 0) {
+    mrb_sys_fail(mrb, "sysread failed");
+  }
+  if (RSTRING_LEN(buf) != ret) {
+    buf = mrb_str_resize(mrb, buf, ret);
+  }
+  if (ret == 0 && maxlen > 0) {
+    mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File");
   }
-
   return buf;
 }
 
-mrb_value
+static mrb_value
 mrb_io_sysseek(mrb_state *mrb, mrb_value io)
 {
   struct mrb_io *fptr;
@@ -899,11 +976,12 @@ mrb_io_sysseek(mrb_state *mrb, mrb_value io)
   }
 }
 
-mrb_value
-mrb_io_syswrite(mrb_state *mrb, mrb_value io)
+static mrb_value
+mrb_io_syswrite_common(mrb_state *mrb,
+    mrb_io_read_write_size (*writefunc)(int, const void *, fsize_t, off_t),
+    mrb_value io, mrb_value buf, off_t offset)
 {
   struct mrb_io *fptr;
-  mrb_value str, buf;
   int fd, length;
 
   fptr = io_get_open_fptr(mrb, io);
@@ -911,19 +989,12 @@ mrb_io_syswrite(mrb_state *mrb, mrb_value io)
     mrb_raise(mrb, E_IO_ERROR, "not opened for writing");
   }
 
-  mrb_get_args(mrb, "S", &str);
-  if (mrb_type(str) != MRB_TT_STRING) {
-    buf = mrb_funcall(mrb, str, "to_s", 0);
-  } else {
-    buf = str;
-  }
-
   if (fptr->fd2 == -1) {
     fd = fptr->fd;
   } else {
     fd = fptr->fd2;
   }
-  length = write(fd, RSTRING_PTR(buf), (fsize_t)RSTRING_LEN(buf));
+  length = writefunc(fd, RSTRING_PTR(buf), (fsize_t)RSTRING_LEN(buf), offset);
   if (length == -1) {
     mrb_sys_fail(mrb, 0);
   }
@@ -931,7 +1002,23 @@ mrb_io_syswrite(mrb_state *mrb, mrb_value io)
   return mrb_fixnum_value(length);
 }
 
-mrb_value
+static mrb_io_read_write_size
+mrb_syswrite_dummy(int fd, const void *buf, fsize_t nbytes, off_t offset)
+{
+  return (mrb_io_read_write_size)write(fd, buf, nbytes);
+}
+
+static mrb_value
+mrb_io_syswrite(mrb_state *mrb, mrb_value io)
+{
+  mrb_value buf;
+
+  mrb_get_args(mrb, "S", &buf);
+
+  return mrb_io_syswrite_common(mrb, mrb_syswrite_dummy, io, buf, 0);
+}
+
+static mrb_value
 mrb_io_close(mrb_state *mrb, mrb_value self)
 {
   struct mrb_io *fptr;
@@ -940,7 +1027,7 @@ mrb_io_close(mrb_state *mrb, mrb_value self)
   return mrb_nil_value();
 }
 
-mrb_value
+static mrb_value
 mrb_io_close_write(mrb_state *mrb, mrb_value self)
 {
   struct mrb_io *fptr;
@@ -951,11 +1038,11 @@ mrb_io_close_write(mrb_state *mrb, mrb_value self)
   return mrb_nil_value();
 }
 
-mrb_value
+static mrb_value
 mrb_io_closed(mrb_state *mrb, mrb_value io)
 {
   struct mrb_io *fptr;
-  fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type);
+  fptr = (struct mrb_io *)mrb_data_get_ptr(mrb, io, &mrb_io_type);
   if (fptr == NULL || fptr->fd >= 0) {
     return mrb_false_value();
   }
@@ -963,7 +1050,7 @@ mrb_io_closed(mrb_state *mrb, mrb_value io)
   return mrb_true_value();
 }
 
-mrb_value
+static mrb_value
 mrb_io_pid(mrb_state *mrb, mrb_value io)
 {
   struct mrb_io *fptr;
@@ -1005,7 +1092,7 @@ static int
 mrb_io_read_data_pending(mrb_state *mrb, mrb_value io)
 {
   mrb_value buf = mrb_iv_get(mrb, io, mrb_intern_cstr(mrb, "@buf"));
-  if (mrb_type(buf) == MRB_TT_STRING && RSTRING_LEN(buf) > 0) {
+  if (mrb_string_p(buf) && RSTRING_LEN(buf) > 0) {
     return 1;
   }
   return 0;
@@ -1068,7 +1155,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
   mrb_get_args(mrb, "*", &argv, &argc);
 
   if (argc < 1 || argc > 4) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1..4)", mrb_fixnum_value(argc));
+    mrb_argnum_error(mrb, argc, 1, 4);
   }
 
   timeout = mrb_nil_value();
@@ -1097,6 +1184,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
     for (i = 0; i < RARRAY_LEN(read); i++) {
       read_io = RARRAY_PTR(read)[i];
       fptr = io_get_open_fptr(mrb, read_io);
+      if (fptr->fd >= FD_SETSIZE) continue;
       FD_SET(fptr->fd, rp);
       if (mrb_io_read_data_pending(mrb, read_io)) {
         pending++;
@@ -1119,6 +1207,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
     FD_ZERO(wp);
     for (i = 0; i < RARRAY_LEN(write); i++) {
       fptr = io_get_open_fptr(mrb, RARRAY_PTR(write)[i]);
+      if (fptr->fd >= FD_SETSIZE) continue;
       FD_SET(fptr->fd, wp);
       if (max < fptr->fd)
         max = fptr->fd;
@@ -1138,6 +1227,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
     FD_ZERO(ep);
     for (i = 0; i < RARRAY_LEN(except); i++) {
       fptr = io_get_open_fptr(mrb, RARRAY_PTR(except)[i]);
+      if (fptr->fd >= FD_SETSIZE) continue;
       FD_SET(fptr->fd, ep);
       if (max < fptr->fd)
         max = fptr->fd;
@@ -1211,15 +1301,22 @@ retry:
   return result;
 }
 
-mrb_value
+int
 mrb_io_fileno(mrb_state *mrb, mrb_value io)
 {
   struct mrb_io *fptr;
   fptr = io_get_open_fptr(mrb, io);
-  return mrb_fixnum_value(fptr->fd);
+  return fptr->fd;
 }
 
-mrb_value
+static mrb_value
+mrb_io_fileno_m(mrb_state *mrb, mrb_value io)
+{
+  int fd = mrb_io_fileno(mrb, io);
+  return mrb_fixnum_value(fd);
+}
+
+static mrb_value
 mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self)
 {
 #if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
@@ -1243,7 +1340,7 @@ mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self)
 #endif
 }
 
-mrb_value
+static mrb_value
 mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self)
 {
 #if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
@@ -1279,7 +1376,7 @@ mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self)
 #endif
 }
 
-mrb_value
+static mrb_value
 mrb_io_set_sync(mrb_state *mrb, mrb_value self)
 {
   struct mrb_io *fptr;
@@ -1291,7 +1388,7 @@ mrb_io_set_sync(mrb_state *mrb, mrb_value self)
   return mrb_bool_value(b);
 }
 
-mrb_value
+static mrb_value
 mrb_io_sync(mrb_state *mrb, mrb_value self)
 {
   struct mrb_io *fptr;
@@ -1299,6 +1396,115 @@ mrb_io_sync(mrb_state *mrb, mrb_value self)
   return mrb_bool_value(fptr->sync);
 }
 
+#ifndef MRB_WITH_IO_PREAD_PWRITE
+# define mrb_io_pread   mrb_notimplement_m
+# define mrb_io_pwrite  mrb_notimplement_m
+#else
+static off_t
+value2off(mrb_state *mrb, mrb_value offv)
+{
+  return (off_t)mrb_int(mrb, offv);
+}
+
+/*
+ * call-seq:
+ *  pread(maxlen, offset, outbuf = "") -> outbuf
+ */
+static mrb_value
+mrb_io_pread(mrb_state *mrb, mrb_value io)
+{
+  mrb_value buf = mrb_nil_value();
+  mrb_value off;
+  mrb_int maxlen;
+
+  mrb_get_args(mrb, "io|S!", &maxlen, &off, &buf);
+
+  return mrb_io_sysread_common(mrb, pread, io, buf, maxlen, value2off(mrb, off));
+}
+
+/*
+ * call-seq:
+ *  pwrite(buffer, offset) -> wrote_bytes
+ */
+static mrb_value
+mrb_io_pwrite(mrb_state *mrb, mrb_value io)
+{
+  mrb_value buf, off;
+
+  mrb_get_args(mrb, "So", &buf, &off);
+
+  return mrb_io_syswrite_common(mrb, pwrite, io, buf, value2off(mrb, off));
+}
+#endif /* MRB_WITH_IO_PREAD_PWRITE */
+
+static mrb_value
+io_bufread(mrb_state *mrb, mrb_value str, mrb_int len)
+{
+  mrb_value str2;
+  mrb_int newlen;
+  struct RString *s;
+  char *p;
+
+  s = RSTRING(str);
+  mrb_str_modify(mrb, s);
+  p = RSTR_PTR(s);
+  str2 = mrb_str_new(mrb, p, len);
+  newlen = RSTR_LEN(s)-len;
+  memmove(p, p+len, newlen);
+  p[newlen] = '\0';
+  RSTR_SET_LEN(s, newlen);
+
+  return str2;
+}
+
+static mrb_value
+mrb_io_bufread(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str;
+  mrb_int len;
+
+  mrb_get_args(mrb, "Si", &str, &len);
+  return io_bufread(mrb, str, len);
+}
+
+static mrb_value
+mrb_io_readchar(mrb_state *mrb, mrb_value self)
+{
+  mrb_value buf;
+  mrb_int len = 1;
+#ifdef MRB_UTF8_STRING
+  unsigned char c;
+#endif
+
+  mrb_get_args(mrb, "S", &buf);
+  mrb_assert(RSTRING_LEN(buf) > 0);
+  mrb_assert(RSTRING_PTR(buf) != NULL);
+  mrb_str_modify(mrb, RSTRING(buf));
+#ifdef MRB_UTF8_STRING
+  c = RSTRING_PTR(buf)[0];
+  if (c & 0x80) {
+    len = mrb_utf8len(RSTRING_PTR(buf), RSTRING_END(buf));
+    if (len == 1 && RSTRING_LEN(buf) < 4) { /* partial UTF-8 */
+      mrb_int blen = RSTRING_LEN(buf);
+      ssize_t n;
+
+      struct mrb_io *fptr = (struct mrb_io*)io_get_open_fptr(mrb, self);
+
+      if (!fptr->readable) {
+        mrb_raise(mrb, E_IO_ERROR, "not opened for reading");
+      }
+      /* refill the buffer */
+      mrb_str_resize(mrb, buf, 4096);
+      n = read(fptr->fd, RSTRING_PTR(buf)+blen, 4096-blen);
+      if (n < 0) mrb_sys_fail(mrb, "sysread failed");
+      mrb_str_resize(mrb, buf, blen+n);
+    }
+    len = mrb_utf8len(RSTRING_PTR(buf), RSTRING_END(buf));
+  }
+#endif
+  return io_bufread(mrb, buf, len);
+}
+
 void
 mrb_init_io(mrb_state *mrb)
 {
@@ -1308,23 +1514,23 @@ mrb_init_io(mrb_state *mrb)
   MRB_SET_INSTANCE_TT(io, MRB_TT_DATA);
 
   mrb_include_module(mrb, io, mrb_module_get(mrb, "Enumerable")); /* 15.2.20.3 */
-  mrb_define_class_method(mrb, io, "_popen",  mrb_io_s_popen,   MRB_ARGS_ANY());
+  mrb_define_class_method(mrb, io, "_popen",  mrb_io_s_popen,   MRB_ARGS_ARG(1,2));
   mrb_define_class_method(mrb, io, "_sysclose",  mrb_io_s_sysclose, MRB_ARGS_REQ(1));
-  mrb_define_class_method(mrb, io, "for_fd",  mrb_io_s_for_fd,   MRB_ARGS_ANY());
-  mrb_define_class_method(mrb, io, "select",  mrb_io_s_select,  MRB_ARGS_ANY());
-  mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ANY());
+  mrb_define_class_method(mrb, io, "for_fd",  mrb_io_s_for_fd,   MRB_ARGS_ARG(1,2));
+  mrb_define_class_method(mrb, io, "select",  mrb_io_s_select,  MRB_ARGS_ARG(1,3));
+  mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ARG(1,2));
 #if !defined(_WIN32) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
   mrb_define_class_method(mrb, io, "_pipe", mrb_io_s_pipe, MRB_ARGS_NONE());
 #endif
 
-  mrb_define_method(mrb, io, "initialize", mrb_io_initialize, MRB_ARGS_ANY());    /* 15.2.20.5.21 (x)*/
+  mrb_define_method(mrb, io, "initialize", mrb_io_initialize, MRB_ARGS_ARG(1,2));    /* 15.2.20.5.21 (x)*/
   mrb_define_method(mrb, io, "initialize_copy", mrb_io_initialize_copy, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, io, "_check_readable", mrb_io_check_readable, MRB_ARGS_NONE());
   mrb_define_method(mrb, io, "isatty",     mrb_io_isatty,     MRB_ARGS_NONE());
   mrb_define_method(mrb, io, "sync",       mrb_io_sync,       MRB_ARGS_NONE());
   mrb_define_method(mrb, io, "sync=",      mrb_io_set_sync,   MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, io, "sysread",    mrb_io_sysread,    MRB_ARGS_ANY());
-  mrb_define_method(mrb, io, "sysseek",    mrb_io_sysseek,    MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, io, "sysread",    mrb_io_sysread,    MRB_ARGS_ARG(1,1));
+  mrb_define_method(mrb, io, "sysseek",    mrb_io_sysseek,    MRB_ARGS_ARG(1,1));
   mrb_define_method(mrb, io, "syswrite",   mrb_io_syswrite,   MRB_ARGS_REQ(1));
   mrb_define_method(mrb, io, "close",      mrb_io_close,      MRB_ARGS_NONE());   /* 15.2.20.5.1 */
   mrb_define_method(mrb, io, "close_write",    mrb_io_close_write,       MRB_ARGS_NONE());
@@ -1332,8 +1538,10 @@ mrb_init_io(mrb_state *mrb)
   mrb_define_method(mrb, io, "close_on_exec?", mrb_io_close_on_exec_p,   MRB_ARGS_NONE());
   mrb_define_method(mrb, io, "closed?",    mrb_io_closed,     MRB_ARGS_NONE());   /* 15.2.20.5.2 */
   mrb_define_method(mrb, io, "pid",        mrb_io_pid,        MRB_ARGS_NONE());   /* 15.2.20.5.2 */
-  mrb_define_method(mrb, io, "fileno",     mrb_io_fileno,     MRB_ARGS_NONE());
-
+  mrb_define_method(mrb, io, "fileno",     mrb_io_fileno_m,   MRB_ARGS_NONE());
+  mrb_define_method(mrb, io, "pread",      mrb_io_pread,      MRB_ARGS_ANY());    /* ruby 2.5 feature */
+  mrb_define_method(mrb, io, "pwrite",     mrb_io_pwrite,     MRB_ARGS_ANY());    /* ruby 2.5 feature */
 
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$/"), mrb_str_new_cstr(mrb, "\n"));
+  mrb_define_method(mrb, io, "_readchar",  mrb_io_readchar,   MRB_ARGS_REQ(1));
+  mrb_define_class_method(mrb, io, "_bufread",   mrb_io_bufread,    MRB_ARGS_REQ(2));
 }
index ba41004..ef4d7fc 100644 (file)
@@ -1,15 +1,13 @@
 ##
 # File Test
 
-assert('File TEST SETUP') do
-  MRubyIOTestUtil.io_test_setup
-end
+MRubyIOTestUtil.io_test_setup
 
-assert('File', '15.2.21') do
+assert('File.class', '15.2.21') do
   assert_equal Class, File.class
 end
 
-assert('File', '15.2.21.2') do
+assert('File.superclass', '15.2.21.2') do
   assert_equal IO, File.superclass
 end
 
@@ -35,6 +33,7 @@ assert('File.basename') do
   assert_equal 'a', File.basename('/a/')
   assert_equal 'b', File.basename('/a/b')
   assert_equal 'b', File.basename('../a/b')
+  assert_raise(ArgumentError) { File.basename("/a/b\0") }
 end
 
 assert('File.dirname') do
@@ -81,6 +80,22 @@ assert('File#mtime') do
   end
 end
 
+assert('File#size and File#truncate') do
+  fname = "#{$mrbtest_io_wfname}.resize"
+  begin
+    File.open(fname, 'w') do |f|
+      assert_equal 0, f.size
+      assert_equal 0, f.truncate(100)
+      assert_equal 100, f.size
+      assert_equal 0, f.pos
+      assert_equal 0, f.truncate(5)
+      assert_equal 5, f.size
+    end
+  ensure
+    File.delete(fname)
+  end
+end
+
 assert('File.join') do
   assert_equal "", File.join()
   assert_equal "a", File.join("a")
@@ -95,24 +110,32 @@ assert('File.join') do
 end
 
 assert('File.realpath') do
-  if File::ALT_SEPARATOR
-    readme_path = File._getwd + File::ALT_SEPARATOR + "README.md"
-    assert_equal readme_path, File.realpath("README.md")
-  else
-    dir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
-    begin
-      dir1 = File.realpath($mrbtest_io_rfname)
-      dir2 = File.realpath("./#{dir}//./../#{$mrbtest_io_symlinkname}")
-      assert_equal dir1, dir2
-    ensure
-      MRubyIOTestUtil.rmdir dir
+  dir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
+  begin
+    sep = File::ALT_SEPARATOR || File::SEPARATOR
+    relative_path = "#{File.basename(dir)}#{sep}realpath_test"
+    path = "#{File._getwd}#{sep}#{relative_path}"
+    File.open(path, "w"){}
+    assert_equal path, File.realpath(relative_path)
+
+    unless MRubyIOTestUtil.win?
+      path1 = File.realpath($mrbtest_io_rfname)
+      path2 = File.realpath($mrbtest_io_symlinkname)
+      assert_equal path1, path2
     end
+  ensure
+    File.delete path rescue nil
+    MRubyIOTestUtil.rmdir dir
   end
+
+  assert_raise(ArgumentError) { File.realpath("TO\0DO") }
 end
 
 assert("File.readlink") do
   begin
-    assert_equal $mrbtest_io_rfname, File.readlink($mrbtest_io_symlinkname)
+    exp = File.basename($mrbtest_io_rfname)
+    act = File.readlink($mrbtest_io_symlinkname)
+    assert_equal exp, act
   rescue NotImplementedError => e
     skip e.message
   end
@@ -178,20 +201,25 @@ end
 
 assert('File.symlink') do
   target_name = "/usr/bin"
-  symlink_name = "test-bin-dummy"
   if !File.exist?(target_name)
     skip("target directory of File.symlink is not found")
-  else
-    begin
-      assert_equal 0, File.symlink(target_name, symlink_name)
-      begin
-        assert_equal true, File.symlink?(symlink_name)
-      ensure
-        File.delete symlink_name
-      end
-    rescue NotImplementedError => e
-      skip e.message
-    end
+  end
+
+  begin
+    tmpdir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
+  rescue => e
+    skip e.message
+  end
+
+  symlink_name = "#{tmpdir}/test-bin-dummy"
+  begin
+    assert_equal 0, File.symlink(target_name, symlink_name)
+    assert_equal true, File.symlink?(symlink_name)
+  rescue NotImplementedError => e
+    skip e.message
+  ensure
+    File.delete symlink_name rescue nil
+    MRubyIOTestUtil.rmdir tmpdir rescue nil
   end
 end
 
@@ -204,6 +232,4 @@ assert('File.chmod') do
   end
 end
 
-assert('File TEST CLEANUP') do
-  assert_nil MRubyIOTestUtil.io_test_cleanup
-end
+MRubyIOTestUtil.io_test_cleanup
index 04e10e0..2134c6a 100644 (file)
@@ -1,9 +1,7 @@
 ##
 # FileTest
 
-assert('FileTest TEST SETUP') do
-  MRubyIOTestUtil.io_test_setup
-end
+MRubyIOTestUtil.io_test_setup
 
 assert("FileTest.directory?") do
   dir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
@@ -22,9 +20,8 @@ assert("FileTest.exist?") do
   assert_equal true,  FileTest.exist?(io), "io obj - exist"
   io.close
   assert_equal true, io.closed?
-  assert_raise IOError do
-    FileTest.exist?(io)
-  end
+  assert_raise(IOError) { FileTest.exist?(io) }
+  assert_raise(TypeError) { File.exist?($mrbtest_io_rfname.to_sym) }
 end
 
 assert("FileTest.file?") do
@@ -112,6 +109,4 @@ assert("FileTest.zero?") do
   assert_true fp2.closed?
 end
 
-assert('FileTest TEST CLEANUP') do
-  assert_nil MRubyIOTestUtil.io_test_cleanup
-end
+MRubyIOTestUtil.io_test_cleanup
index 85852c1..2088a61 100644 (file)
@@ -1,35 +1,50 @@
 ##
 # IO Test
 
-assert('IO TEST SETUP') do
-  MRubyIOTestUtil.io_test_setup
-  $cr = MRubyIOTestUtil.win? ? 1 : 0  # "\n" include CR or not
+MRubyIOTestUtil.io_test_setup
+$cr, $crlf, $cmd = MRubyIOTestUtil.win? ? [1, "\r\n", "cmd /c "] : [0, "\n", ""]
+
+def assert_io_open(meth)
+  assert "assert_io_open" do
+    fd = IO.sysopen($mrbtest_io_rfname)
+    assert_equal Fixnum, fd.class
+    io1 = IO.__send__(meth, fd)
+    begin
+      assert_equal IO, io1.class
+      assert_equal $mrbtest_io_msg, io1.read
+    ensure
+      io1.close
+    end
+
+    io2 = IO.__send__(meth, IO.sysopen($mrbtest_io_rfname))do |io|
+      if meth == :open
+        assert_equal $mrbtest_io_msg, io.read
+      else
+        flunk "IO.#{meth} does not take block"
+      end
+    end
+    io2.close unless meth == :open
+
+    assert_raise(RuntimeError) { IO.__send__(meth, 1023) } # For Windows
+    assert_raise(RuntimeError) { IO.__send__(meth, 1 << 26) }
+    assert_raise(RuntimeError) { IO.__send__(meth, 1 << 32) } if (1 << 32).kind_of?(Integer)
+  end
 end
 
-assert('IO', '15.2.20') do
+assert('IO.class', '15.2.20') do
   assert_equal(Class, IO.class)
 end
 
-assert('IO', '15.2.20.2') do
+assert('IO.superclass', '15.2.20.2') do
   assert_equal(Object, IO.superclass)
 end
 
-assert('IO', '15.2.20.3') do
+assert('IO.ancestors', '15.2.20.3') do
   assert_include(IO.ancestors, Enumerable)
 end
 
 assert('IO.open', '15.2.20.4.1') do
-  fd = IO.sysopen $mrbtest_io_rfname
-  assert_equal Fixnum, fd.class
-  io = IO.open fd
-  assert_equal IO, io.class
-  assert_equal $mrbtest_io_msg, io.read
-  io.close
-
-  fd = IO.sysopen $mrbtest_io_rfname
-  IO.open(fd) do |io|
-    assert_equal $mrbtest_io_msg, io.read
-  end
+  assert_io_open(:open)
 end
 
 assert('IO#close', '15.2.20.5.1') do
@@ -84,7 +99,7 @@ end
 
 assert('IO#getc', '15.2.20.5.8') do
   io = IO.new(IO.sysopen($mrbtest_io_rfname))
-  $mrbtest_io_msg.each_char { |ch|
+  $mrbtest_io_msg.split("").each { |ch|
     assert_equal ch, io.getc
   }
   assert_equal nil, io.getc
@@ -118,16 +133,17 @@ end
 
 assert "IO#read(n) with n > IO::BUF_SIZE" do
   skip "pipe is not supported on this platform" if MRubyIOTestUtil.win?
-  r,w = IO.pipe
-  n = IO::BUF_SIZE+1
-  w.write 'a'*n
-  assert_equal r.read(n), 'a'*n
+  IO.pipe do |r,w|
+    n = IO::BUF_SIZE+1
+    w.write 'a'*n
+    assert_equal 'a'*n, r.read(n)
+  end
 end
 
 assert('IO#readchar', '15.2.20.5.15') do
   # almost same as IO#getc
   IO.open(IO.sysopen($mrbtest_io_rfname)) do |io|
-    $mrbtest_io_msg.each_char { |ch|
+    $mrbtest_io_msg.split("").each { |ch|
       assert_equal ch, io.readchar
     }
     assert_raise(EOFError) do
@@ -215,19 +231,15 @@ assert('IO#dup for writable') do
 end
 
 assert('IO.for_fd') do
-  fd = IO.sysopen($mrbtest_io_rfname)
-  io = IO.for_fd(fd)
-    assert_equal $mrbtest_io_msg, io.read
-  io.close
+  assert_io_open(:for_fd)
 end
 
 assert('IO.new') do
-  io = IO.new(0)
-  io.close
+  assert_io_open(:new)
 end
 
 assert('IO gc check') do
-  100.times { IO.new(0) }
+  assert_nothing_raised { 100.times { IO.new(0) } }
 end
 
 assert('IO.sysopen("./nonexistent")') do
@@ -419,7 +431,7 @@ end
 assert('IO.popen') do
   begin
     $? = nil
-    io = IO.popen("echo mruby-io")
+    io = IO.popen("#{$cmd}echo mruby-io")
     assert_true io.close_on_exec?
     assert_equal Fixnum, io.pid.class
 
@@ -556,6 +568,34 @@ assert('IO#sysseek') do
   end
 end
 
+assert('IO#pread') do
+  skip "IO#pread is not implemented on this configuration" unless MRubyIOTestUtil::MRB_WITH_IO_PREAD_PWRITE
+
+  IO.open(IO.sysopen($mrbtest_io_rfname, 'r'), 'r') do |io|
+    assert_equal $mrbtest_io_msg.byteslice(5, 8), io.pread(8, 5)
+    assert_equal 0, io.pos
+    assert_equal $mrbtest_io_msg.byteslice(1, 5), io.pread(5, 1)
+    assert_equal 0, io.pos
+    assert_raise(RuntimeError) { io.pread(20, -9) }
+  end
+end
+
+assert('IO#pwrite') do
+  skip "IO#pwrite is not implemented on this configuration" unless MRubyIOTestUtil::MRB_WITH_IO_PREAD_PWRITE
+
+  IO.open(IO.sysopen($mrbtest_io_wfname, 'w+'), 'w+') do |io|
+    assert_equal 6, io.pwrite("Warld!", 7)
+    assert_equal 0, io.pos
+    assert_equal 7, io.pwrite("Hello, ", 0)
+    assert_equal 0, io.pos
+    assert_equal "Hello, Warld!", io.read
+    assert_equal 6, io.pwrite("world!", 7)
+    assert_equal 13, io.pos
+    io.pos = 0
+    assert_equal "Hello, world!", io.read
+  end
+end
+
 assert('IO.pipe') do
   begin
     called = false
@@ -598,12 +638,10 @@ end
 
 assert('`cmd`') do
   begin
-    assert_equal `echo foo`, "foo\n"
+    assert_equal `#{$cmd}echo foo`, "foo#{$crlf}"
   rescue NotImplementedError => e
     skip e.message
   end
 end
 
-assert('IO TEST CLEANUP') do
-  assert_nil MRubyIOTestUtil.io_test_cleanup
-end
+MRubyIOTestUtil.io_test_cleanup
index 71239a8..8bc87a0 100644 (file)
@@ -1,5 +1,7 @@
+#include <mruby/common.h>
 #include <sys/types.h>
 #include <errno.h>
+#include <string.h>
 
 #if defined(_WIN32) || defined(_WIN64)
 
@@ -7,7 +9,6 @@
 #include <io.h>
 #include <fcntl.h>
 #include <direct.h>
-#include <string.h>
 #include <stdlib.h>
 #include <malloc.h>
 
@@ -18,7 +19,9 @@ typedef int mode_t;
 #define open _open
 #define close _close
 
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || \
+    (defined(MRB_MINGW32_VERSION) && MRB_MINGW32_VERSION < 3021) || \
+    (defined(MRB_MINGW64_VERSION) && MRB_MINGW64_VERSION < 4000)
 #include <sys/stat.h>
 
 static int
@@ -50,10 +53,11 @@ mkdtemp(char *temp)
   #include <sys/socket.h>
   #include <unistd.h>
   #include <sys/un.h>
+  #include <fcntl.h>
+  #include <libgen.h>
 #endif
 
 #include <sys/stat.h>
-#include <stdio.h>
 #include <stdlib.h>
 
 #include "mruby.h"
@@ -61,51 +65,55 @@ mkdtemp(char *temp)
 #include "mruby/error.h"
 #include "mruby/string.h"
 #include "mruby/variable.h"
+#include <mruby/ext/io.h>
 
 static mrb_value
 mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
 {
-  char rfname[]      = "tmp.mruby-io-test-r.XXXXXXXX";
-  char wfname[]      = "tmp.mruby-io-test-w.XXXXXXXX";
-  char symlinkname[] = "tmp.mruby-io-test-l.XXXXXXXX";
-  char socketname[]  = "tmp.mruby-io-test-s.XXXXXXXX";
+#define GVNAME(n) "$mrbtest_io_" #n "name"
+  enum {IDX_READ, IDX_WRITE, IDX_LINK, IDX_SOCKET, IDX_COUNT};
+  const char *gvnames[] = {GVNAME(rf), GVNAME(wf), GVNAME(symlink), GVNAME(socket)};
+  char *fnames[IDX_COUNT];
+  int fds[IDX_COUNT];
   char msg[] = "mruby io test\n";
   mode_t mask;
-  int fd0, fd1;
   FILE *fp;
-
+  int i;
 #if !defined(_WIN32) && !defined(_WIN64)
-  int fd2, fd3;
   struct sockaddr_un sun0;
 #endif
 
-  mask = umask(077);
-  fd0 = mkstemp(rfname);
-  fd1 = mkstemp(wfname);
-  if (fd0 == -1 || fd1 == -1) {
-    mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
-    return mrb_nil_value();
-  }
-  close(fd0);
-  close(fd1);
+  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_str_new_cstr(mrb, msg));
 
+  mask = umask(077);
+  for (i = 0; i < IDX_COUNT; i++) {
+    mrb_value fname = mrb_str_new_capa(mrb, 0);
 #if !defined(_WIN32) && !defined(_WIN64)
-  fd2 = mkstemp(symlinkname);
-  fd3 = mkstemp(socketname);
-  if (fd2 == -1 || fd3 == -1) {
-    mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
-    return mrb_nil_value();
-  }
+    /*
+     * Workaround for not being able to bind a socket to some file systems
+     * (e.g. vboxsf, NFS). [#4981]
+     */
+    char *tmpdir = getenv("TMPDIR");
+    if (tmpdir && strlen(tmpdir) > 0) {
+      mrb_str_cat_cstr(mrb, fname, tmpdir);
+      if (*(RSTRING_END(fname)-1) != '/') mrb_str_cat_lit(mrb, fname, "/");
+    } else {
+      mrb_str_cat_lit(mrb, fname, "/tmp/");
+    }
 #endif
+    mrb_str_cat_cstr(mrb, fname, gvnames[i]+1);
+    mrb_str_cat_cstr(mrb, fname, ".XXXXXXXX");
+    fnames[i] = RSTRING_PTR(fname);
+    fds[i] = mkstemp(fnames[i]);
+    if (fds[i] == -1) {
+      mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
+    }
+    close(fds[i]);
+    mrb_gv_set(mrb, mrb_intern_cstr(mrb, gvnames[i]), fname);
+  }
   umask(mask);
 
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_rfname"), mrb_str_new_cstr(mrb, rfname));
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_wfname"), mrb_str_new_cstr(mrb, wfname));
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"), mrb_str_new_cstr(mrb, symlinkname));
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"), mrb_str_new_cstr(mrb, socketname));
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_str_new_cstr(mrb, msg));
-
-  fp = fopen(rfname, "wb");
+  fp = fopen(fnames[IDX_READ], "wb");
   if (fp == NULL) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file");
     return mrb_nil_value();
@@ -113,7 +121,7 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
   fputs(msg, fp);
   fclose(fp);
 
-  fp = fopen(wfname, "wb");
+  fp = fopen(fnames[IDX_WRITE], "wb");
   if (fp == NULL) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file");
     return mrb_nil_value();
@@ -121,29 +129,29 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
   fclose(fp);
 
 #if !defined(_WIN32) && !defined(_WIN64)
-  unlink(symlinkname);
-  close(fd2);
-  if (symlink(rfname, symlinkname) == -1) {
+  unlink(fnames[IDX_LINK]);
+  if (symlink(basename(fnames[IDX_READ]), fnames[IDX_LINK]) == -1) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a symbolic link");
   }
 
-  unlink(socketname);
-  close(fd3);
-  fd3 = socket(AF_UNIX, SOCK_STREAM, 0);
-  if (fd3 == -1) {
+  unlink(fnames[IDX_SOCKET]);
+  fds[IDX_SOCKET] = socket(AF_UNIX, SOCK_STREAM, 0);
+  if (fds[IDX_SOCKET] == -1) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a socket");
   }
   sun0.sun_family = AF_UNIX;
-  snprintf(sun0.sun_path, sizeof(sun0.sun_path), "%s", socketname);
-  if (bind(fd3, (struct sockaddr *)&sun0, sizeof(sun0)) == -1) {
-    mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %S: %S",
-               mrb_str_new_cstr(mrb, sun0.sun_path),
-               mrb_fixnum_value(errno));
+  strncpy(sun0.sun_path, fnames[IDX_SOCKET], sizeof(sun0.sun_path)-1);
+  sun0.sun_path[sizeof(sun0.sun_path)-1] = 0;
+  if (bind(fds[IDX_SOCKET], (struct sockaddr *)&sun0, sizeof(sun0)) == -1) {
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %s: %d",
+               sun0.sun_path,
+               errno);
   }
-  close(fd3);
+  close(fds[IDX_SOCKET]);
 #endif
 
   return mrb_true_value();
+#undef GVNAME
 }
 
 static mrb_value
@@ -154,16 +162,16 @@ mrb_io_test_io_cleanup(mrb_state *mrb, mrb_value self)
   mrb_value symlinkname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"));
   mrb_value socketname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"));
 
-  if (mrb_type(rfname) == MRB_TT_STRING) {
+  if (mrb_string_p(rfname)) {
     remove(RSTRING_PTR(rfname));
   }
-  if (mrb_type(wfname) == MRB_TT_STRING) {
+  if (mrb_string_p(wfname)) {
     remove(RSTRING_PTR(wfname));
   }
-  if (mrb_type(symlinkname) == MRB_TT_STRING) {
+  if (mrb_string_p(symlinkname)) {
     remove(RSTRING_PTR(symlinkname));
   }
-  if (mrb_type(socketname) == MRB_TT_STRING) {
+  if (mrb_string_p(socketname)) {
     remove(RSTRING_PTR(socketname));
   }
 
@@ -177,28 +185,6 @@ mrb_io_test_io_cleanup(mrb_state *mrb, mrb_value self)
 }
 
 static mrb_value
-mrb_io_test_file_setup(mrb_state *mrb, mrb_value self)
-{
-  mrb_value ary = mrb_io_test_io_setup(mrb, self);
-#if !defined(_WIN32) && !defined(_WIN64)
-  if (symlink("/usr/bin", "test-bin") == -1) {
-    mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a symbolic link");
-  }
-#endif
-
-  return ary;
-}
-
-static mrb_value
-mrb_io_test_file_cleanup(mrb_state *mrb, mrb_value self)
-{
-  mrb_io_test_io_cleanup(mrb, self);
-  remove("test-bin");
-
-  return mrb_nil_value();
-}
-
-static mrb_value
 mrb_io_test_mkdtemp(mrb_state *mrb, mrb_value klass)
 {
   mrb_value str;
@@ -215,18 +201,16 @@ mrb_io_test_mkdtemp(mrb_state *mrb, mrb_value klass)
 static mrb_value
 mrb_io_test_rmdir(mrb_state *mrb, mrb_value klass)
 {
-  mrb_value str;
-  char *cp;
+  const char *cp;
 
-  mrb_get_args(mrb, "S", &str);
-  cp = mrb_str_to_cstr(mrb, str);
+  mrb_get_args(mrb, "z", &cp);
   if (rmdir(cp) == -1) {
     mrb_sys_fail(mrb, "rmdir");
   }
   return mrb_true_value();
 }
 
-mrb_value
+static mrb_value
 mrb_io_win_p(mrb_state *mrb, mrb_value klass)
 {
 #if defined(_WIN32) || defined(_WIN64)
@@ -240,6 +224,12 @@ mrb_io_win_p(mrb_state *mrb, mrb_value klass)
 #endif
 }
 
+#ifdef MRB_WITH_IO_PREAD_PWRITE
+# define MRB_WITH_IO_PREAD_PWRITE_ENABLED TRUE
+#else
+# define MRB_WITH_IO_PREAD_PWRITE_ENABLED FALSE
+#endif
+
 void
 mrb_mruby_io_gem_test(mrb_state* mrb)
 {
@@ -247,10 +237,9 @@ mrb_mruby_io_gem_test(mrb_state* mrb)
   mrb_define_class_method(mrb, io_test, "io_test_setup", mrb_io_test_io_setup, MRB_ARGS_NONE());
   mrb_define_class_method(mrb, io_test, "io_test_cleanup", mrb_io_test_io_cleanup, MRB_ARGS_NONE());
 
-  mrb_define_class_method(mrb, io_test, "file_test_setup", mrb_io_test_file_setup, MRB_ARGS_NONE());
-  mrb_define_class_method(mrb, io_test, "file_test_cleanup", mrb_io_test_file_cleanup, MRB_ARGS_NONE());
-
   mrb_define_class_method(mrb, io_test, "mkdtemp", mrb_io_test_mkdtemp, MRB_ARGS_REQ(1));
   mrb_define_class_method(mrb, io_test, "rmdir", mrb_io_test_rmdir, MRB_ARGS_REQ(1));
   mrb_define_class_method(mrb, io_test, "win?", mrb_io_win_p, MRB_ARGS_NONE());
+
+  mrb_define_const(mrb, io_test, "MRB_WITH_IO_PREAD_PWRITE", mrb_bool_value(MRB_WITH_IO_PREAD_PWRITE_ENABLED));
 }
index fcb3a83..e52c63a 100644 (file)
@@ -1,5 +1,5 @@
 MRuby::Gem::Specification.new('mruby-kernel-ext') do |spec|
   spec.license = 'MIT'
   spec.author  = 'mruby developers'
-  spec.summary = 'Kernel module extension'
+  spec.summary = 'extensional function-like methods'
 end
diff --git a/third-party/mruby/mrbgems/mruby-kernel-ext/mrblib/kernel.rb b/third-party/mruby/mrbgems/mruby-kernel-ext/mrblib/kernel.rb
deleted file mode 100644 (file)
index bf739ed..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-module Kernel
-  # call-seq:
-  #   obj.yield_self {|_obj|...} -> an_object
-  #   obj.then {|_obj|...}       -> an_object
-  #
-  # Yields <i>obj</i> and returns the result.
-  #
-  #   'my string'.yield_self {|s|s.upcase} #=> "MY STRING"
-  #
-  def yield_self(&block)
-    return to_enum :yield_self unless block
-    block.call(self)
-  end
-  alias then yield_self
-end
index 99affbf..1d183ae 100644 (file)
@@ -20,9 +20,9 @@ mrb_f_caller(mrb_state *mrb, mrb_value self)
       n = bt_len - lev;
       break;
     case 1:
-      if (mrb_type(v) == MRB_TT_RANGE) {
+      if (mrb_range_p(v)) {
         mrb_int beg, len;
-        if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == 1) {
+        if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == MRB_RANGE_OK) {
           lev = beg;
           n = len;
         }
@@ -31,22 +31,21 @@ mrb_f_caller(mrb_state *mrb, mrb_value self)
         }
       }
       else {
-        v = mrb_to_int(mrb, v);
-        lev = mrb_fixnum(v);
+        lev = mrb_int(mrb, v);
         if (lev < 0) {
-          mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v);
+          mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v);
         }
         n = bt_len - lev;
       }
       break;
     case 2:
-      lev = mrb_fixnum(mrb_to_int(mrb, v));
-      n = mrb_fixnum(mrb_to_int(mrb, length));
+      lev = mrb_int(mrb, v);
+      n = mrb_int(mrb, length);
       if (lev < 0) {
-        mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v);
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v);
       }
       if (n < 0) {
-        mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%S)", length);
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%v)", length);
       }
       break;
     default:
@@ -129,9 +128,8 @@ mrb_f_integer(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_f_float(mrb_state *mrb, mrb_value self)
 {
-  mrb_value arg;
+  mrb_value arg = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &arg);
   return mrb_Float(mrb, arg);
 }
 #endif
@@ -150,9 +148,9 @@ mrb_f_float(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_f_string(mrb_state *mrb, mrb_value self)
 {
-  mrb_value arg, tmp;
+  mrb_value arg = mrb_get_arg1(mrb);
+  mrb_value tmp;
 
-  mrb_get_args(mrb, "o", &arg);
   tmp = mrb_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_s");
   return tmp;
 }
@@ -169,9 +167,9 @@ mrb_f_string(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_f_array(mrb_state *mrb, mrb_value self)
 {
-  mrb_value arg, tmp;
+  mrb_value arg = mrb_get_arg1(mrb);
+  mrb_value tmp;
 
-  mrb_get_args(mrb, "o", &arg);
   tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_a");
   if (mrb_nil_p(tmp)) {
     return mrb_ary_new_from_values(mrb, 1, &arg);
@@ -197,31 +195,14 @@ mrb_f_array(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_f_hash(mrb_state *mrb, mrb_value self)
 {
-  mrb_value arg;
+  mrb_value arg = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &arg);
   if (mrb_nil_p(arg) || (mrb_array_p(arg) && RARRAY_LEN(arg) == 0)) {
     return mrb_hash_new(mrb);
   }
   return mrb_ensure_hash_type(mrb, arg);
 }
 
-/*
- *  call-seq:
- *     obj.itself -> an_object
- *
- *  Returns <i>obj</i>.
- *
- *      string = 'my string' #=> "my string"
- *      string.itself.object_id == string.object_id #=> true
- *
- */
-static mrb_value
-mrb_f_itself(mrb_state *mrb, mrb_value self)
-{
-  return self;
-}
-
 void
 mrb_mruby_kernel_ext_gem_init(mrb_state *mrb)
 {
@@ -230,14 +211,13 @@ mrb_mruby_kernel_ext_gem_init(mrb_state *mrb)
   mrb_define_module_function(mrb, krn, "fail", mrb_f_raise, MRB_ARGS_OPT(2));
   mrb_define_module_function(mrb, krn, "caller", mrb_f_caller, MRB_ARGS_OPT(2));
   mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE());
-  mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ANY());
+  mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ARG(1,1));
 #ifndef MRB_WITHOUT_FLOAT
   mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1));
 #endif
   mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1));
   mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1));
   mrb_define_module_function(mrb, krn, "Hash", mrb_f_hash, MRB_ARGS_REQ(1));
-  mrb_define_module_function(mrb, krn, "itself", mrb_f_itself, MRB_ARGS_NONE());
 }
 
 void
index 28f0890..cf78faa 100644 (file)
@@ -49,22 +49,52 @@ assert('Kernel#__method__') do
 end
 
 assert('Kernel#Integer') do
-  assert_equal(26, Integer("0x1a"))
-  assert_equal(930, Integer("0930", 10))
-  assert_equal(7, Integer("111", 2))
-  assert_equal(0, Integer("0"))
-  assert_equal(0, Integer("00000"))
+  assert_operator(26, :eql?, Integer("0x1a"))
+  assert_operator(930, :eql?, Integer("0930", 10))
+  assert_operator(7, :eql?, Integer("111", 2))
+  assert_operator(0, :eql?, Integer("0"))
+  assert_operator(0, :eql?, Integer("00000"))
+  assert_operator(123, :eql?, Integer('1_2_3'))
+  assert_operator(123, :eql?, Integer("\t\r\n\f\v 123 \t\r\n\f\v"))
   assert_raise(TypeError) { Integer(nil) }
+  assert_raise(ArgumentError) { Integer('a') }
+  assert_raise(ArgumentError) { Integer('4a5') }
+  assert_raise(ArgumentError) { Integer('1_2__3') }
+  assert_raise(ArgumentError) { Integer('68_') }
+  assert_raise(ArgumentError) { Integer('68_ ') }
+  assert_raise(ArgumentError) { Integer('_68') }
+  assert_raise(ArgumentError) { Integer(' _68') }
+  assert_raise(ArgumentError) { Integer('6 8') }
+  assert_raise(ArgumentError) { Integer("15\0") }
+  assert_raise(ArgumentError) { Integer("15.0") }
   skip unless Object.const_defined?(:Float)
-  assert_equal(123, Integer(123.999))
+  assert_operator(123, :eql?, Integer(123.999))
 end
 
 assert('Kernel#Float') do
   skip unless Object.const_defined?(:Float)
-  assert_equal(1.0, Float(1))
-  assert_equal(123.456, Float(123.456))
-  assert_equal(123.456, Float("123.456"))
+  assert_operator(1.0, :eql?, Float(1))
+  assert_operator(123.456, :eql?, Float(123.456))
+  assert_operator(123.456, :eql?, Float("123.456"))
+  assert_operator(123.0, :eql?, Float('1_2_3'))
+  assert_operator(12.34, :eql?, Float('1_2.3_4'))
+  assert_operator(0.9, :eql?, Float('.9'))
+  assert_operator(0.9, :eql?, Float(" \t\r\n\f\v.9 \t\r\n\f\v"))
+  assert_operator(16.0, :eql?, Float("0x10"))
   assert_raise(TypeError) { Float(nil) }
+  assert_raise(ArgumentError) { Float("1. 5") }
+  assert_raise(ArgumentError) { Float("1.5a") }
+  assert_raise(ArgumentError) { Float("1.5\0") }
+  assert_raise(ArgumentError) { Float('a') }
+  assert_raise(ArgumentError) { Float('4a5') }
+  assert_raise(ArgumentError) { Float('1_2__3') }
+  assert_raise(ArgumentError) { Float('68_') }
+  assert_raise(ArgumentError) { Float('68._7') }
+  assert_raise(ArgumentError) { Float('68.7_') }
+  assert_raise(ArgumentError) { Float('68.7_ ') }
+  assert_raise(ArgumentError) { Float('_68') }
+  assert_raise(ArgumentError) { Float(' _68') }
+  assert_raise(ArgumentError) { Float('1_2.3__4') }
 end
 
 assert('Kernel#String') do
index caa16b7..88b3377 100644 (file)
@@ -4,6 +4,10 @@
 ** See Copyright Notice in mruby.h
 */
 
+#ifdef MRB_WITHOUT_FLOAT
+# error Math conflicts 'MRB_WITHOUT_FLOAT' configuration in your 'build_config.rb'
+#endif
+
 #include <mruby.h>
 #include <mruby/array.h>
 
@@ -14,8 +18,7 @@ domain_error(mrb_state *mrb, const char *func)
 {
   struct RClass *math = mrb_module_get(mrb, "Math");
   struct RClass *domainerror = mrb_class_get_under(mrb, math, "DomainError");
-  mrb_value str = mrb_str_new_cstr(mrb, func);
-  mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %S", str);
+  mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %s", func);
 }
 
 /* math functions not provided by Microsoft Visual C++ 2012 or older */
index 86a4fc1..d2790e2 100644 (file)
@@ -1,6 +1,14 @@
 ##
 # Math Test
 
+def assert_float_and_int(exp_ary, act_ary)
+  assert('assert_float_and_int') do
+    flo_exp, int_exp, flo_act, int_act = *exp_ary, *act_ary
+    assert_float(flo_exp, flo_act)
+    assert_operator(int_exp, :eql?, int_act)
+  end
+end
+
 assert('Math.sin 0') do
   assert_float(0, Math.sin(0))
 end
@@ -109,12 +117,6 @@ assert('Math.hypot') do
   assert_float(5.0, Math.hypot(3, 4))
 end
 
-assert('Math.frexp 1234') do
-  n = 1234
-  fraction, exponent = Math.frexp(n)
-  assert_float(n, Math.ldexp(fraction, exponent))
-end
-
 assert('Math.erf 1') do
   assert_float(0.842700792949715, Math.erf(1))
 end
@@ -130,3 +132,108 @@ end
 assert('Math.erfc -1') do
   assert_float(1.8427007929497148, Math.erfc(-1))
 end
+
+assert('Math.acos') do
+  assert_float(0 * Math::PI / 4, Math.acos( 1.0))
+  assert_float(1 * Math::PI / 4, Math.acos( 1.0 / Math.sqrt(2)))
+  assert_float(2 * Math::PI / 4, Math.acos( 0.0))
+  assert_float(4 * Math::PI / 4, Math.acos(-1.0))
+  assert_raise(Math::DomainError) { Math.acos(+1.1) }
+  assert_raise(Math::DomainError) { Math.acos(-1.1) }
+end
+
+assert('Math.asin') do
+  assert_float( 0 * Math::PI / 4, Math.asin( 0.0))
+  assert_float( 1 * Math::PI / 4, Math.asin( 1.0 / Math.sqrt(2)))
+  assert_float( 2 * Math::PI / 4, Math.asin( 1.0))
+  assert_float(-2 * Math::PI / 4, Math.asin(-1.0))
+  assert_raise(Math::DomainError) { Math.asin(+1.1) }
+  assert_raise(Math::DomainError) { Math.asin(-1.1) }
+  assert_raise(Math::DomainError) { Math.asin(2.0) }
+end
+
+assert('Math.atan') do
+  assert_float( 0 * Math::PI / 4, Math.atan( 0.0))
+  assert_float( 1 * Math::PI / 4, Math.atan( 1.0))
+  assert_float( 2 * Math::PI / 4, Math.atan(1.0 / 0.0))
+  assert_float(-1 * Math::PI / 4, Math.atan(-1.0))
+end
+
+assert('Math.cosh') do
+  assert_float(1, Math.cosh(0))
+  assert_float((Math::E ** 1 + Math::E ** -1) / 2, Math.cosh(1))
+  assert_float((Math::E ** 2 + Math::E ** -2) / 2, Math.cosh(2))
+end
+
+assert('Math.sinh') do
+  assert_float(0, Math.sinh(0))
+  assert_float((Math::E ** 1 - Math::E ** -1) / 2, Math.sinh(1))
+  assert_float((Math::E ** 2 - Math::E ** -2) / 2, Math.sinh(2))
+end
+
+assert('Math.tanh') do
+  assert_float(Math.sinh(0) / Math.cosh(0), Math.tanh(0))
+  assert_float(Math.sinh(1) / Math.cosh(1), Math.tanh(1))
+  assert_float(Math.sinh(2) / Math.cosh(2), Math.tanh(2))
+  assert_float(+1.0, Math.tanh(+1000.0))
+  assert_float(-1.0, Math.tanh(-1000.0))
+end
+
+assert('Math.acosh') do
+  assert_float(0, Math.acosh(1))
+  assert_float(1, Math.acosh((Math::E ** 1 + Math::E ** -1) / 2))
+  assert_float(2, Math.acosh((Math::E ** 2 + Math::E ** -2) / 2))
+  assert_raise(Math::DomainError) { Math.acosh(0.9) }
+  assert_raise(Math::DomainError) { Math.acosh(0) }
+end
+
+assert('Math.asinh') do
+  assert_float(0, Math.asinh(0))
+  assert_float(1, Math.asinh((Math::E ** 1 - Math::E ** -1) / 2))
+  assert_float(2, Math.asinh((Math::E ** 2 - Math::E ** -2) / 2))
+end
+
+assert('Math.atanh') do
+  assert_float(0, Math.atanh(Math.sinh(0) / Math.cosh(0)))
+  assert_float(1, Math.atanh(Math.sinh(1) / Math.cosh(1)))
+  assert_float(2, Math.atanh(Math.sinh(2) / Math.cosh(2)))
+  assert_float(Float::INFINITY, Math.atanh(1))
+  assert_float(-Float::INFINITY, Math.atanh(-1))
+  assert_raise(Math::DomainError) { Math.atanh(+1.1) }
+  assert_raise(Math::DomainError) { Math.atanh(-1.1) }
+end
+
+assert('Math.atan2') do
+  assert_float(+0.0, Math.atan2(+0.0, +0.0))
+  assert_float(-0.0, Math.atan2(-0.0, +0.0))
+  assert_float(+Math::PI, Math.atan2(+0.0, -0.0))
+  assert_float(-Math::PI, Math.atan2(-0.0, -0.0))
+
+  inf = Float::INFINITY
+  expected = 3.0 * Math::PI / 4.0
+  assert_float(+expected, Math.atan2(+inf, -inf))
+  assert_float(-expected, Math.atan2(-inf, -inf))
+  expected = Math::PI / 4.0
+  assert_float(+expected, Math.atan2(+inf, +inf))
+  assert_float(-expected, Math.atan2(-inf, +inf))
+
+  assert_float(0, Math.atan2(0, 1))
+  assert_float(Math::PI / 4, Math.atan2(1, 1))
+  assert_float(Math::PI / 2, Math.atan2(1, 0))
+end
+
+assert('Math.ldexp') do
+  assert_float(0.0, Math.ldexp(0.0, 0.0))
+  assert_float(0.5, Math.ldexp(0.5, 0.0))
+  assert_float(1.0, Math.ldexp(0.5, 1.0))
+  assert_float(2.0, Math.ldexp(0.5, 2.0))
+  assert_float(3.0, Math.ldexp(0.75, 2.0))
+end
+
+assert('Math.frexp') do
+  assert_float_and_int([0.0,  0], Math.frexp(0.0))
+  assert_float_and_int([0.5,  0], Math.frexp(0.5))
+  assert_float_and_int([0.5,  1], Math.frexp(1.0))
+  assert_float_and_int([0.5,  2], Math.frexp(2.0))
+  assert_float_and_int([0.75, 2], Math.frexp(3.0))
+end
index 0aafb4c..6c0dc5a 100644 (file)
@@ -117,6 +117,7 @@ mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
 }
 
 /* 15.3.1.2.7 */
+/* 15.3.1.3.28 */
 /*
  *  call-seq:
  *     local_variables   -> array
@@ -138,31 +139,30 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)
 
   proc = mrb->c->ci[-1].proc;
 
-  if (MRB_PROC_CFUNC_P(proc)) {
+  if (proc == NULL || MRB_PROC_CFUNC_P(proc)) {
     return mrb_ary_new(mrb);
   }
   vars = mrb_hash_new(mrb);
   while (proc) {
     if (MRB_PROC_CFUNC_P(proc)) break;
     irep = proc->body.irep;
-    if (!irep->lv) break;
-    for (i = 0; i + 1 < irep->nlocals; ++i) {
-      if (irep->lv[i].name) {
-        mrb_sym sym = irep->lv[i].name;
-        const char *name = mrb_sym2name(mrb, sym);
-        switch (name[0]) {
-        case '*': case '&':
-          break;
-        default:
-          mrb_hash_set(mrb, vars, mrb_symbol_value(sym), mrb_true_value());
-          break;
+    if (irep->lv) {
+      for (i = 0; i + 1 < irep->nlocals; ++i) {
+        if (irep->lv[i].name) {
+          mrb_sym sym = irep->lv[i].name;
+          const char *name = mrb_sym_name(mrb, sym);
+          switch (name[0]) {
+          case '*': case '&':
+            break;
+          default:
+            mrb_hash_set(mrb, vars, mrb_symbol_value(sym), mrb_true_value());
+            break;
+          }
         }
       }
     }
-    if (!MRB_PROC_ENV_P(proc)) break;
+    if (MRB_PROC_SCOPE_P(proc)) break;
     proc = proc->upper;
-    //if (MRB_PROC_SCOPE_P(proc)) break;
-    if (!proc->c) break;
   }
 
   return mrb_hash_keys(mrb, vars);
@@ -171,7 +171,7 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)
 KHASH_DECLARE(st, mrb_sym, char, FALSE)
 
 static void
-method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set)
+method_entry_loop(mrb_state *mrb, struct RClass *klass, khash_t(st) *set, khash_t(st) *undef)
 {
   khint_t i;
 
@@ -180,20 +180,28 @@ method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set)
   for (i=0;i<kh_end(h);i++) {
     if (kh_exist(h, i)) {
       mrb_method_t m = kh_value(h, i);
-      if (MRB_METHOD_UNDEF_P(m)) continue;
-      kh_put(st, mrb, set, kh_key(h, i));
+      if (MRB_METHOD_UNDEF_P(m)) {
+        if (undef) {
+          kh_put(st, mrb, undef, kh_key(h, i));
+        }
+      }
+      else if (undef == NULL ||
+               kh_get(st, mrb, undef, kh_key(h, i)) == kh_end(undef)) {
+        kh_put(st, mrb, set, kh_key(h, i));
+      }
     }
   }
 }
 
-mrb_value
-mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClassklass, int obj)
+static mrb_value
+mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *klass, int obj)
 {
   khint_t i;
   mrb_value ary;
   mrb_bool prepended = FALSE;
-  struct RClass* oldklass;
-  khash_t(st)* set = kh_init(st, mrb);
+  struct RClass *oldklass;
+  khash_t(st) *set = kh_init(st, mrb);
+  khash_t(st) *undef = (recur ? kh_init(st, mrb) : NULL);
 
   if (!recur && (klass->flags & MRB_FL_CLASS_IS_PREPENDED)) {
     MRB_CLASS_ORIGIN(klass);
@@ -202,7 +210,7 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl
 
   oldklass = 0;
   while (klass && (klass != oldklass)) {
-    method_entry_loop(mrb, klass, set);
+    method_entry_loop(mrb, klass, set, undef);
     if ((klass->tt == MRB_TT_ICLASS && !prepended) ||
         (klass->tt == MRB_TT_SCLASS)) {
     }
@@ -220,6 +228,7 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl
     }
   }
   kh_destroy(st, mrb, set);
+  if (undef) kh_destroy(st, mrb, undef);
 
   return ary;
 }
@@ -312,18 +321,19 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)
 {
   khint_t i;
   mrb_value ary;
-  struct RClass* klass;
-  khash_t(st)* set = kh_init(st, mrb);
+  struct RClass *klass;
+  khash_t(st) *set = kh_init(st, mrb);
+  khash_t(st) *undef = (recur ? kh_init(st, mrb) : NULL);
 
   klass = mrb_class(mrb, obj);
 
   if (klass && (klass->tt == MRB_TT_SCLASS)) {
-      method_entry_loop(mrb, klass, set);
+      method_entry_loop(mrb, klass, set, undef);
       klass = klass->super;
   }
   if (recur) {
       while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) {
-        method_entry_loop(mrb, klass, set);
+        method_entry_loop(mrb, klass, set, undef);
         klass = klass->super;
       }
   }
@@ -335,6 +345,7 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)
     }
   }
   kh_destroy(st, mrb, set);
+  if (undef) kh_destroy(st, mrb, undef);
 
   return ary;
 }
@@ -388,10 +399,7 @@ mod_define_singleton_method(mrb_state *mrb, mrb_value self)
   mrb_sym mid;
   mrb_value blk = mrb_nil_value();
 
-  mrb_get_args(mrb, "n&", &mid, &blk);
-  if (mrb_nil_p(blk)) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
-  }
+  mrb_get_args(mrb, "n&!", &mid, &blk);
   p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
   mrb_proc_copy(p, mrb_proc_ptr(blk));
   p->flags |= MRB_PROC_STRICT;
@@ -411,9 +419,9 @@ static void
 check_cv_name_sym(mrb_state *mrb, mrb_sym id)
 {
   mrb_int len;
-  const char *name = mrb_sym2name_len(mrb, id, &len);
+  const char *name = mrb_sym_name_len(mrb, id, &len);
   if (!cv_name_p(mrb, name, len)) {
-    mrb_name_error(mrb, id, "'%S' is not allowed as a class variable name", mrb_sym2str(mrb, id));
+    mrb_name_error(mrb, id, "'%n' is not allowed as a class variable name", id);
   }
 }
 
@@ -453,12 +461,10 @@ mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod)
   if (!mrb_undef_p(val)) return val;
 
   if (mrb_cv_defined(mrb, mod, id)) {
-    mrb_name_error(mrb, id, "cannot remove %S for %S",
-                   mrb_sym2str(mrb, id), mod);
+    mrb_name_error(mrb, id, "cannot remove %n for %v", id, mod);
   }
 
-  mrb_name_error(mrb, id, "class variable %S not defined for %S",
-                 mrb_sym2str(mrb, id), mod);
+  mrb_name_error(mrb, id, "class variable %n not defined for %v", id, mod);
 
  /* not reached */
  return mrb_nil_value();
@@ -565,8 +571,6 @@ mrb_mod_included_modules(mrb_state *mrb, mrb_value self)
   return result;
 }
 
-mrb_value mrb_class_instance_method_list(mrb_state*, mrb_bool, struct RClass*, int);
-
 /* 15.2.2.4.33 */
 /*
  *  call-seq:
@@ -623,8 +627,7 @@ remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid)
     }
   }
 
-  mrb_name_error(mrb, mid, "method '%S' not defined in %S",
-                 mrb_sym2str(mrb, mid), mod);
+  mrb_name_error(mrb, mid, "method '%n' not defined in %v", mid, mod);
 }
 
 /* 15.2.2.4.41 */
@@ -643,6 +646,7 @@ mrb_mod_remove_method(mrb_state *mrb, mrb_value mod)
   mrb_value *argv;
 
   mrb_get_args(mrb, "*", &argv, &argc);
+  mrb_check_frozen(mrb, mrb_obj_ptr(mod));
   while (argc--) {
     remove_method(mrb, mod, mrb_obj_to_sym(mrb, *argv));
     argv++;
@@ -657,8 +661,28 @@ mrb_mod_s_constants(mrb_state *mrb, mrb_value mod)
   return mrb_nil_value();       /* not reached */
 }
 
-/* implementation of Module.nesting */
-mrb_value mrb_mod_s_nesting(mrb_state*, mrb_value);
+static mrb_value
+mrb_mod_s_nesting(mrb_state *mrb, mrb_value mod)
+{
+  struct RProc *proc;
+  mrb_value ary;
+  struct RClass *c = NULL;
+
+  ary = mrb_ary_new(mrb);
+  proc = mrb->c->ci[-1].proc;   /* callee proc */
+  while (proc && !MRB_PROC_CFUNC_P(proc)) {
+    if (MRB_PROC_SCOPE_P(proc)) {
+      struct RClass *c2 = MRB_PROC_TARGET_CLASS(proc);
+
+      if (c2 != c) {
+        c = c2;
+        mrb_ary_push(mrb, ary, mrb_obj_value(c));
+      }
+    }
+    proc = proc->upper;
+  }
+  return ary;
+}
 
 void
 mrb_mruby_metaprog_gem_init(mrb_state* mrb)
@@ -666,8 +690,8 @@ mrb_mruby_metaprog_gem_init(mrb_state* mrb)
   struct RClass *krn = mrb->kernel_module;
   struct RClass *mod = mrb->module_class;
 
-  mrb_define_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.2.4 */
-  mrb_define_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.3.28 */
+  mrb_define_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.3.14 (15.3.1.2.4) */
+  mrb_define_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.3.28 (15.3.1.2.7) */
 
   mrb_define_method(mrb, krn, "singleton_class", mrb_singleton_class, MRB_ARGS_NONE());
   mrb_define_method(mrb, krn, "instance_variable_defined?", mrb_obj_ivar_defined, MRB_ARGS_REQ(1)); /* 15.3.1.3.20 */
@@ -679,10 +703,10 @@ mrb_mruby_metaprog_gem_init(mrb_state* mrb)
   mrb_define_method(mrb, krn, "protected_methods", mrb_obj_protected_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.37 */
   mrb_define_method(mrb, krn, "public_methods", mrb_obj_public_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.38 */
   mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.45 */
-  mrb_define_method(mrb, krn, "define_singleton_method", mod_define_singleton_method, MRB_ARGS_ANY());
-  mrb_define_method(mrb, krn, "send", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.44 */
+  mrb_define_method(mrb, krn, "define_singleton_method", mod_define_singleton_method, MRB_ARGS_REQ(1)|MRB_ARGS_BLOCK());
+  mrb_define_method(mrb, krn, "send", mrb_f_send, MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()); /* 15.3.1.3.44 */
 
-  mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, MRB_ARGS_NONE()); /* 15.2.2.4.19 */
+  mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, MRB_ARGS_OPT(1)); /* 15.2.2.4.19 */
   mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */
   mrb_define_method(mrb, mod, "class_variable_defined?", mrb_mod_cvar_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.16 */
   mrb_define_method(mrb, mod, "class_variable_get", mrb_mod_cvar_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.17 */
@@ -693,7 +717,7 @@ mrb_mruby_metaprog_gem_init(mrb_state* mrb)
   mrb_define_method(mrb, mod, "method_removed", mrb_f_nil, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, mod, "constants", mrb_mod_constants, MRB_ARGS_OPT(1)); /* 15.2.2.4.24 */
   mrb_define_class_method(mrb, mod, "constants", mrb_mod_s_constants, MRB_ARGS_ANY()); /* 15.2.2.3.1 */
-  mrb_define_class_method(mrb, mod, "nesting", mrb_mod_s_nesting, MRB_ARGS_REQ(0)); /* 15.2.2.3.2 */
+  mrb_define_class_method(mrb, mod, "nesting", mrb_mod_s_nesting, MRB_ARGS_NONE()); /* 15.2.2.3.2 */
 }
 
 void
index 1262c99..82ba0a3 100644 (file)
@@ -1,17 +1,3 @@
-assert('Kernel#__send__', '15.3.1.3.4') do
-  # test with block
-  l = __send__(:lambda) do
-    true
-  end
-
-  assert_true l.call
-  assert_equal Proc, l.class
-  # test with argument
-  assert_true __send__(:respond_to?, :nil?)
-  # test without argument and without block
-  assert_equal String, __send__(:to_s).class
-end
-
 assert('Kernel#send', '15.3.1.3.44') do
   # test with block
   l = send(:lambda) do
@@ -58,6 +44,8 @@ assert('Kernel#instance_variable_set', '15.3.1.3.22') do
   %w[@6 @% @@a @ a].each do |n|
     assert_raise(NameError) { o.instance_variable_set(n, 1) }
   end
+  assert_raise(FrozenError) { o.freeze.instance_variable_set(:@a, 2) }
+  assert_raise(FrozenError, ArgumentError) { nil.instance_variable_set(:@a, 2) }
 end
 
 assert('Kernel#instance_variables', '15.3.1.3.23') do
@@ -99,6 +87,21 @@ assert('Kernel#singleton_methods', '15.3.1.3.45') do
   assert_equal singleton_methods.class, Array
 end
 
+assert('Kernel.global_variables', '15.3.1.2.4') do
+  assert_equal Array, Kernel.global_variables.class
+end
+
+assert('Kernel#global_variables', '15.3.1.3.14') do
+  variables1 = global_variables
+  assert_equal Array, variables1.class
+  assert_not_include(variables1, :$kernel_global_variables_test)
+
+  $kernel_global_variables_test = nil
+  variables2 = global_variables
+  assert_include(variables2, :$kernel_global_variables_test)
+  assert_equal(1, variables2.size - variables1.size)
+end
+
 assert('Kernel.local_variables', '15.3.1.2.7') do
   a, b = 0, 1
   a += b
@@ -111,6 +114,15 @@ assert('Kernel.local_variables', '15.3.1.2.7') do
     # Kernel#local_variables: 15.3.1.3.28
     local_variables.sort
   }.call(-1, -2)
+
+  a = Object.new
+  def a.hoge(vars, *, **)
+    Proc.new {
+      x, y = 1, 2
+      local_variables.sort
+    }
+  end
+  assert_equal([:vars, :x, :y]) { a.hoge(0).call }
 end
 
 assert('Kernel#define_singleton_method') do
@@ -120,6 +132,24 @@ assert('Kernel#define_singleton_method') do
   end
   assert_equal :test_method, ret
   assert_equal :singleton_method_ok, o.test_method
+  assert_raise(TypeError) { 2.define_singleton_method(:f){} }
+  assert_raise(FrozenError) { [].freeze.define_singleton_method(:f){} }
+end
+
+assert('Kernel#singleton_class') do
+  o1 = Object.new
+  assert_same(o1.singleton_class, class << o1; self end)
+
+  o2 = Object.new
+  sc2 = class << o2; self end
+  assert_same(o2.singleton_class, sc2)
+
+  o3 = Object.new
+  sc3 = o3.singleton_class
+  o3.freeze
+  assert_predicate(sc3, :frozen?)
+
+  assert_predicate(Object.new.freeze.singleton_class, :frozen?)
 end
 
 def labeled_module(name, &block)
@@ -171,7 +201,6 @@ assert('Module#class_variable_set', '15.2.2.4.18') do
       @@foo
     end
   end
-
   assert_equal 99, Test4ClassVariableSet.class_variable_set(:@@cv, 99)
   assert_equal 101, Test4ClassVariableSet.class_variable_set(:@@foo, 101)
   assert_true Test4ClassVariableSet.class_variables.include? :@@cv
@@ -180,6 +209,13 @@ assert('Module#class_variable_set', '15.2.2.4.18') do
   %w[@@ @@1 @@x= @x @ x 1].each do |n|
     assert_raise(NameError) { Test4ClassVariableSet.class_variable_set(n, 1) }
   end
+
+  m = Module.new.freeze
+  assert_raise(FrozenError) { m.class_variable_set(:@@cv, 1) }
+
+  parent = Class.new{ class_variable_set(:@@a, nil) }.freeze
+  child = Class.new(parent)
+  assert_raise(FrozenError) { child.class_variable_set(:@@a, 1) }
 end
 
 assert('Module#class_variables', '15.2.2.4.19') do
@@ -261,6 +297,9 @@ assert('Module#remove_class_variable', '15.2.2.4.39') do
   assert_raise(NameError) do
     Test4RemoveClassVariable.remove_class_variable(:@v)
   end
+  assert_raise(FrozenError) do
+    Test4RemoveClassVariable.freeze.remove_class_variable(:@@cv)
+  end
 end
 
 assert('Module#remove_method', '15.2.2.4.41') do
@@ -268,9 +307,9 @@ assert('Module#remove_method', '15.2.2.4.41') do
     class Parent
       def hello
       end
-     end
+    end
 
-     class Child < Parent
+    class Child < Parent
       def hello
       end
     end
@@ -280,6 +319,7 @@ assert('Module#remove_method', '15.2.2.4.41') do
   assert_same klass, klass.class_eval{ remove_method :hello }
   assert_true klass.instance_methods.include? :hello
   assert_false klass.instance_methods(false).include? :hello
+  assert_raise(FrozenError) { klass.freeze.remove_method :m }
 end
 
 assert('Module.nesting', '15.2.2.2.2') do
index f7cefa2..56af7cf 100644 (file)
@@ -6,18 +6,6 @@ class Method
     }
   end
 
-  def owner
-    @owner
-  end
-
-  def receiver
-    @recv
-  end
-
-  def name
-    @name
-  end
-
   def <<(other)
     ->(*args, &block) { call(other.call(*args, &block)) }
   end
diff --git a/third-party/mruby/mrbgems/mruby-method/mrblib/unbound_method.rb b/third-party/mruby/mrbgems/mruby-method/mrblib/unbound_method.rb
deleted file mode 100644 (file)
index 1d3acf3..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-class UnboundMethod
-  def owner
-    @owner
-  end
-
-  def name
-    @name
-  end
-end
index fa89856..111b031 100644 (file)
@@ -11,34 +11,37 @@ method_object_alloc(mrb_state *mrb, struct RClass *mclass)
   return (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mclass);
 }
 
+static void
+bind_check(mrb_state *mrb, mrb_value recv, mrb_value owner)
+{
+  if (!mrb_module_p(owner) &&
+      mrb_class_ptr(owner) != mrb_obj_class(mrb, recv) &&
+      !mrb_obj_is_kind_of(mrb, recv, mrb_class_ptr(owner))) {
+    if (mrb_sclass_p(owner)) {
+      mrb_raise(mrb, E_TYPE_ERROR, "singleton method called for a different object");
+    } else {
+      mrb_raisef(mrb, E_TYPE_ERROR, "bind argument must be an instance of %v", owner);
+    }
+  }
+}
+
 static mrb_value
 unbound_method_bind(mrb_state *mrb, mrb_value self)
 {
   struct RObject *me;
-  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@owner"));
-  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name"));
-  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "proc"));
-  mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@klass"));
-  mrb_value recv;
-
-  mrb_get_args(mrb, "o", &recv);
+  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
+  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
+  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
+  mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
+  mrb_value recv = mrb_get_arg1(mrb);
 
-  if (mrb_type(owner) != MRB_TT_MODULE &&
-      mrb_class_ptr(owner) != mrb_obj_class(mrb, recv) &&
-      !mrb_obj_is_kind_of(mrb, recv, mrb_class_ptr(owner))) {
-        if (mrb_type(owner) == MRB_TT_SCLASS) {
-          mrb_raise(mrb, E_TYPE_ERROR, "singleton method called for a different object");
-        } else {
-          const char *s = mrb_class_name(mrb, mrb_class_ptr(owner));
-          mrb_raisef(mrb, E_TYPE_ERROR, "bind argument must be an instance of %S", mrb_str_new_static(mrb, s, strlen(s)));
-        }
-  }
+  bind_check(mrb, recv, owner);
   me = method_object_alloc(mrb, mrb_class_get(mrb, "Method"));
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@owner"), owner);
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@recv"), recv);
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@name"), name);
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "proc"), proc);
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@klass"), klass);
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_owner"), owner);
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_recv"), recv);
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_name"), name);
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_proc"), proc);
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_klass"), klass);
 
   return mrb_obj_value(me);
 }
@@ -47,33 +50,33 @@ unbound_method_bind(mrb_state *mrb, mrb_value self)
 static mrb_value
 method_eql(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other, receiver, orig_proc, other_proc;
+  mrb_value other = mrb_get_arg1(mrb);
+  mrb_value receiver, orig_proc, other_proc;
   struct RClass *owner, *klass;
   struct RProc *orig_rproc, *other_rproc;
 
-  mrb_get_args(mrb, "o", &other);
   if (!mrb_obj_is_instance_of(mrb, other, mrb_class(mrb, self)))
     return mrb_false_value();
 
   if (mrb_class(mrb, self) != mrb_class(mrb, other))
     return mrb_false_value();
 
-  klass = mrb_class_ptr(IV_GET(self, "@klass"));
-  if (klass != mrb_class_ptr(IV_GET(other, "@klass")))
+  klass = mrb_class_ptr(IV_GET(self, "_klass"));
+  if (klass != mrb_class_ptr(IV_GET(other, "_klass")))
     return mrb_false_value();
 
-  owner = mrb_class_ptr(IV_GET(self, "@owner"));
-  if (owner != mrb_class_ptr(IV_GET(other, "@owner")))
+  owner = mrb_class_ptr(IV_GET(self, "_owner"));
+  if (owner != mrb_class_ptr(IV_GET(other, "_owner")))
     return mrb_false_value();
 
-  receiver = IV_GET(self, "@recv");
-  if (!mrb_obj_equal(mrb, receiver, IV_GET(other, "@recv")))
+  receiver = IV_GET(self, "_recv");
+  if (!mrb_obj_equal(mrb, receiver, IV_GET(other, "_recv")))
     return mrb_false_value();
 
-  orig_proc = IV_GET(self, "proc");
-  other_proc = IV_GET(other, "proc");
+  orig_proc = IV_GET(self, "_proc");
+  other_proc = IV_GET(other, "_proc");
   if (mrb_nil_p(orig_proc) && mrb_nil_p(other_proc)) {
-    if (mrb_symbol(IV_GET(self, "@name")) == mrb_symbol(IV_GET(other, "@name")))
+    if (mrb_symbol(IV_GET(self, "_name")) == mrb_symbol(IV_GET(other, "_name")))
       return mrb_true_value();
     else
       return mrb_false_value();
@@ -105,18 +108,12 @@ method_eql(mrb_state *mrb, mrb_value self)
 #undef IV_GET
 
 static mrb_value
-method_call(mrb_state *mrb, mrb_value self)
+mcall(mrb_state *mrb, mrb_value recv, mrb_value proc, mrb_value name, struct RClass *owner,
+      mrb_int argc, mrb_value *argv, mrb_value block)
 {
-  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "proc"));
-  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name"));
-  mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@recv"));
-  struct RClass *owner = mrb_class_ptr(mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@owner")));
-  mrb_int argc;
-  mrb_value *argv, ret, block;
-  mrb_sym orig_mid;
+  mrb_value ret;
+  mrb_sym orig_mid = mrb->c->ci->mid;
 
-  mrb_get_args(mrb, "*&", &argv, &argc, &block);
-  orig_mid = mrb->c->ci->mid;
   mrb->c->ci->mid = mrb_symbol(name);
   if (mrb_nil_p(proc)) {
     mrb_value missing_argv = mrb_ary_new_from_values(mrb, argc, argv);
@@ -138,20 +135,49 @@ method_call(mrb_state *mrb, mrb_value self)
 }
 
 static mrb_value
+method_call(mrb_state *mrb, mrb_value self)
+{
+  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
+  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
+  mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
+  struct RClass *owner = mrb_class_ptr(mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner")));
+  mrb_int argc;
+  mrb_value *argv, block;
+
+  mrb_get_args(mrb, "*&", &argv, &argc, &block);
+  return mcall(mrb, recv, proc, name, owner, argc, argv, block);
+}
+
+static mrb_value
+method_bcall(mrb_state *mrb, mrb_value self)
+{
+  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
+  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
+  mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
+  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
+  mrb_int argc;
+  mrb_value *argv, block;
+
+  mrb_get_args(mrb, "o*&", &recv, &argv, &argc, &block);
+  bind_check(mrb, recv, owner);
+  return mcall(mrb, recv, proc, name, mrb_class_ptr(owner), argc, argv, block);
+}
+
+static mrb_value
 method_unbind(mrb_state *mrb, mrb_value self)
 {
   struct RObject *ume;
-  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@owner"));
-  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name"));
-  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "proc"));
-  mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@klass"));
+  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
+  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
+  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
+  mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
 
   ume = method_object_alloc(mrb, mrb_class_get(mrb, "UnboundMethod"));
-  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "@owner"), owner);
-  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "@recv"), mrb_nil_value());
-  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "@name"), name);
-  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "proc"), proc);
-  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "@klass"), klass);
+  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_owner"), owner);
+  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_recv"), mrb_nil_value());
+  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_name"), name);
+  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_proc"), proc);
+  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_klass"), klass);
 
   return mrb_obj_value(ume);
 }
@@ -170,10 +196,10 @@ method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
 static mrb_value
 method_super_method(mrb_state *mrb, mrb_value self)
 {
-  mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@recv"));
-  mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@klass"));
-  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@owner"));
-  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name"));
+  mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
+  mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
+  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
+  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
   struct RClass *super, *rklass;
   struct RProc *proc;
   struct RObject *me;
@@ -199,11 +225,11 @@ method_super_method(mrb_state *mrb, mrb_value self)
     super = super->c;
 
   me = method_object_alloc(mrb, mrb_obj_class(mrb, self));
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@owner"), mrb_obj_value(super));
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@recv"), recv);
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@name"), name);
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "proc"), mrb_obj_value(proc));
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@klass"), mrb_obj_value(rklass));
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_owner"), mrb_obj_value(super));
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_recv"), recv);
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_name"), name);
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_proc"), mrb_obj_value(proc));
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_klass"), mrb_obj_value(rklass));
 
   return mrb_obj_value(me);
 }
@@ -211,26 +237,15 @@ method_super_method(mrb_state *mrb, mrb_value self)
 static mrb_value
 method_arity(mrb_state *mrb, mrb_value self)
 {
-  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "proc"));
-  struct RProc *rproc;
-  struct RClass *orig;
-  mrb_value ret;
-
-  if (mrb_nil_p(proc))
-    return mrb_fixnum_value(-1);
-
-  rproc = mrb_proc_ptr(proc);
-  orig = rproc->c;
-  rproc->c = mrb->proc_class;
-  ret = mrb_funcall(mrb, proc, "arity", 0);
-  rproc->c = orig;
-  return ret;
+  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
+  mrb_int arity = mrb_nil_p(proc) ? -1 : mrb_proc_arity(mrb_proc_ptr(proc));
+  return mrb_fixnum_value(arity);
 }
 
 static mrb_value
 method_source_location(mrb_state *mrb, mrb_value self)
 {
-  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "proc"));
+  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
   struct RProc *rproc;
   struct RClass *orig;
   mrb_value ret;
@@ -249,7 +264,7 @@ method_source_location(mrb_state *mrb, mrb_value self)
 static mrb_value
 method_parameters(mrb_state *mrb, mrb_value self)
 {
-  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "proc"));
+  mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
   struct RProc *rproc;
   struct RClass *orig;
   mrb_value ret;
@@ -271,9 +286,9 @@ method_parameters(mrb_state *mrb, mrb_value self)
 static mrb_value
 method_to_s(mrb_state *mrb, mrb_value self)
 {
-  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@owner"));
-  mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@klass"));
-  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name"));
+  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
+  mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
+  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
   mrb_value str = mrb_str_new_lit(mrb, "#<");
   struct RClass *rklass;
 
@@ -281,16 +296,16 @@ method_to_s(mrb_state *mrb, mrb_value self)
   mrb_str_cat_lit(mrb, str, ": ");
   rklass = mrb_class_ptr(klass);
   if (mrb_class_ptr(owner) == rklass) {
-    mrb_str_cat_str(mrb, str, mrb_funcall(mrb, owner, "to_s", 0));
+    mrb_str_concat(mrb, str, owner);
     mrb_str_cat_lit(mrb, str, "#");
-    mrb_str_cat_str(mrb, str, mrb_funcall(mrb, name, "to_s", 0));
+    mrb_str_concat(mrb, str, name);
   }
   else {
     mrb_str_cat_cstr(mrb, str, mrb_class_name(mrb, rklass));
     mrb_str_cat_lit(mrb, str, "(");
-    mrb_str_cat_str(mrb, str, mrb_funcall(mrb, owner, "to_s", 0));
+    mrb_str_concat(mrb, str, owner);
     mrb_str_cat_lit(mrb, str, ")#");
-    mrb_str_cat_str(mrb, str, mrb_funcall(mrb, name, "to_s", 0));
+    mrb_str_concat(mrb, str, name);
   }
   mrb_str_cat_lit(mrb, str, ">");
   return str;
@@ -300,7 +315,6 @@ static void
 mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym name, struct RClass **owner, struct RProc **proc, mrb_bool unbound)
 {
   mrb_value ret;
-  const char *s;
 
   *owner = c;
   *proc = method_search_vm(mrb, owner, name);
@@ -324,13 +338,7 @@ mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym
   return;
 
 name_error:
-  s = mrb_class_name(mrb, c);
-  mrb_raisef(
-    mrb, E_NAME_ERROR,
-    "undefined method '%S' for class '%S'",
-    mrb_sym2str(mrb, name),
-    mrb_str_new_static(mrb, s, strlen(s))
-  );
+  mrb_raisef(mrb, E_NAME_ERROR, "undefined method '%n' for class '%C'", name, c);
 }
 
 static mrb_value
@@ -346,11 +354,11 @@ mrb_kernel_method(mrb_state *mrb, mrb_value self)
   mrb_search_method_owner(mrb, mrb_class(mrb, self), self, name, &owner, &proc, FALSE);
 
   me = method_object_alloc(mrb, mrb_class_get(mrb, "Method"));
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@owner"), mrb_obj_value(owner));
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@recv"), self);
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@name"), mrb_symbol_value(name));
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "proc"), proc ? mrb_obj_value(proc) : mrb_nil_value());
-  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@klass"), mrb_obj_value(mrb_class(mrb, self)));
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_owner"), mrb_obj_value(owner));
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_recv"), self);
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_name"), mrb_symbol_value(name));
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_proc"), proc ? mrb_obj_value(proc) : mrb_nil_value());
+  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_klass"), mrb_obj_value(mrb_class(mrb, self)));
 
   return mrb_obj_value(me);
 }
@@ -368,15 +376,33 @@ mrb_module_instance_method(mrb_state *mrb, mrb_value self)
   mrb_search_method_owner(mrb, mrb_class_ptr(self), self, name, &owner, &proc, TRUE);
 
   ume = method_object_alloc(mrb, mrb_class_get(mrb, "UnboundMethod"));
-  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "@owner"), mrb_obj_value(owner));
-  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "@recv"), mrb_nil_value());
-  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "@name"), mrb_symbol_value(name));
-  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "proc"), proc ? mrb_obj_value(proc) : mrb_nil_value());
-  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "@klass"), self);
+  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_owner"), mrb_obj_value(owner));
+  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_recv"), mrb_nil_value());
+  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_name"), mrb_symbol_value(name));
+  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_proc"), proc ? mrb_obj_value(proc) : mrb_nil_value());
+  mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_klass"), self);
 
   return mrb_obj_value(ume);
 }
 
+static mrb_value
+method_owner(mrb_state *mrb, mrb_value self)
+{
+  return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
+}
+
+static mrb_value
+method_receiver(mrb_state *mrb, mrb_value self)
+{
+  return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
+}
+
+static mrb_value
+method_name(mrb_state *mrb, mrb_value self)
+{
+  return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
+}
+
 void
 mrb_mruby_method_gem_init(mrb_state* mrb)
 {
@@ -387,25 +413,31 @@ mrb_mruby_method_gem_init(mrb_state* mrb)
   mrb_define_method(mrb, unbound_method, "bind", unbound_method_bind, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, unbound_method, "super_method", method_super_method, MRB_ARGS_NONE());
   mrb_define_method(mrb, unbound_method, "==", method_eql, MRB_ARGS_REQ(1));
-  mrb_define_alias(mrb,  unbound_method, "eql?", "==");
+  mrb_define_method(mrb, unbound_method, "eql?", method_eql, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, unbound_method, "to_s", method_to_s, MRB_ARGS_NONE());
   mrb_define_method(mrb, unbound_method, "inspect", method_to_s, MRB_ARGS_NONE());
   mrb_define_method(mrb, unbound_method, "arity", method_arity, MRB_ARGS_NONE());
   mrb_define_method(mrb, unbound_method, "source_location", method_source_location, MRB_ARGS_NONE());
   mrb_define_method(mrb, unbound_method, "parameters", method_parameters, MRB_ARGS_NONE());
+  mrb_define_method(mrb, unbound_method, "bind_call", method_bcall, MRB_ARGS_REQ(1)|MRB_ARGS_ANY());
+  mrb_define_method(mrb, unbound_method, "owner", method_owner, MRB_ARGS_NONE());
+  mrb_define_method(mrb, unbound_method, "name", method_name, MRB_ARGS_NONE());
 
   mrb_undef_class_method(mrb, method, "new");
   mrb_define_method(mrb, method, "==", method_eql, MRB_ARGS_REQ(1));
-  mrb_define_alias(mrb,  method, "eql?", "==");
+  mrb_define_method(mrb, method, "eql?", method_eql, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, method, "to_s", method_to_s, MRB_ARGS_NONE());
   mrb_define_method(mrb, method, "inspect", method_to_s, MRB_ARGS_NONE());
   mrb_define_method(mrb, method, "call", method_call, MRB_ARGS_ANY());
-  mrb_define_alias(mrb,  method, "[]", "call");
+  mrb_define_method(mrb, method, "[]", method_call, MRB_ARGS_ANY());
   mrb_define_method(mrb, method, "unbind", method_unbind, MRB_ARGS_NONE());
   mrb_define_method(mrb, method, "super_method", method_super_method, MRB_ARGS_NONE());
   mrb_define_method(mrb, method, "arity", method_arity, MRB_ARGS_NONE());
   mrb_define_method(mrb, method, "source_location", method_source_location, MRB_ARGS_NONE());
   mrb_define_method(mrb, method, "parameters", method_parameters, MRB_ARGS_NONE());
+  mrb_define_method(mrb, method, "owner", method_owner, MRB_ARGS_NONE());
+  mrb_define_method(mrb, method, "receiver", method_receiver, MRB_ARGS_NONE());
+  mrb_define_method(mrb, method, "name", method_name, MRB_ARGS_NONE());
 
   mrb_define_method(mrb, mrb->kernel_module, "method", mrb_kernel_method, MRB_ARGS_REQ(1));
 
index dfddde9..641979d 100644 (file)
@@ -21,7 +21,7 @@ class Interpreter
   }
   def interpret(string)
     @ret = ""
-    string.each_char {|b| Dispatcher[b].bind(self).call }
+    string.split("").each {|b| Dispatcher[b].bind(self).call }
   end
 end
 
@@ -441,3 +441,11 @@ assert 'UnboundMethod#bind' do
   assert_raise(TypeError) { Array.instance_method(:each).bind(1) }
   assert_kind_of Method, Object.instance_method(:object_id).bind(Object.new)
 end
+
+assert 'UnboundMethod#bind_call' do
+  m = Array.instance_method(:size)
+  assert_equal(:size, m.name)
+  assert_equal(0, m.bind_call([]))
+  assert_equal(1, m.bind_call([1]))
+  assert_equal(2, m.bind_call([1,2]))
+end
index f250538..576605c 100644 (file)
@@ -1,8 +1,4 @@
-module Integral
-  def div(other)
-    self.divmod(other)[0]
-  end
-
+class Numeric
   def zero?
     self == 0
   end
index cd8bbf1..f8aff54 100644 (file)
@@ -1,38 +1,6 @@
 #include <limits.h>
 #include <mruby.h>
-
-static inline mrb_int
-to_int(mrb_state *mrb, mrb_value x)
-{
-  x = mrb_to_int(mrb, x);
-  return mrb_fixnum(x);
-}
-
-/*
- *  Document-method: Integer#chr
- *  call-seq:
- *     int.chr  ->  string
- *
- *  Returns a string containing the character represented by the +int+'s value
- *  according to +encoding+.
- *
- *     65.chr    #=> "A"
- *     230.chr   #=> "\xE6"
- */
-static mrb_value
-mrb_int_chr(mrb_state *mrb, mrb_value x)
-{
-  mrb_int chr;
-  char c;
-
-  chr = to_int(mrb, x);
-  if (chr >= (1 << CHAR_BIT)) {
-    mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", x);
-  }
-  c = (char)chr;
-
-  return mrb_str_new(mrb, &c, 1);
-}
+#include <mruby/numeric.h>
 
 /*
  *  call-seq:
@@ -46,7 +14,7 @@ mrb_int_allbits(mrb_state *mrb, mrb_value self)
   mrb_int n, m;
 
   mrb_get_args(mrb, "i", &m);
-  n = to_int(mrb, self);
+  n = mrb_int(mrb, self);
   return mrb_bool_value((n & m) == m);
 }
 
@@ -62,7 +30,7 @@ mrb_int_anybits(mrb_state *mrb, mrb_value self)
   mrb_int n, m;
 
   mrb_get_args(mrb, "i", &m);
-  n = to_int(mrb, self);
+  n = mrb_int(mrb, self);
   return mrb_bool_value((n & m) != 0);
 }
 
@@ -78,7 +46,7 @@ mrb_int_nobits(mrb_state *mrb, mrb_value self)
   mrb_int n, m;
 
   mrb_get_args(mrb, "i", &m);
-  n = to_int(mrb, self);
+  n = mrb_int(mrb, self);
   return mrb_bool_value((n & m) == 0);
 }
 
@@ -87,10 +55,22 @@ mrb_mruby_numeric_ext_gem_init(mrb_state* mrb)
 {
   struct RClass *i = mrb_module_get(mrb, "Integral");
 
-  mrb_define_method(mrb, i, "chr", mrb_int_chr, MRB_ARGS_NONE());
   mrb_define_method(mrb, i, "allbits?", mrb_int_allbits, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, i, "anybits?", mrb_int_anybits, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, i, "nobits?", mrb_int_nobits, MRB_ARGS_REQ(1));
+
+#ifndef MRB_WITHOUT_FLOAT
+  mrb_define_const(mrb, mrb->float_class, "RADIX",        mrb_fixnum_value(MRB_FLT_RADIX));
+  mrb_define_const(mrb, mrb->float_class, "MANT_DIG",     mrb_fixnum_value(MRB_FLT_MANT_DIG));
+  mrb_define_const(mrb, mrb->float_class, "EPSILON",      mrb_float_value(mrb, MRB_FLT_EPSILON));
+  mrb_define_const(mrb, mrb->float_class, "DIG",          mrb_fixnum_value(MRB_FLT_DIG));
+  mrb_define_const(mrb, mrb->float_class, "MIN_EXP",      mrb_fixnum_value(MRB_FLT_MIN_EXP));
+  mrb_define_const(mrb, mrb->float_class, "MIN",          mrb_float_value(mrb, MRB_FLT_MIN));
+  mrb_define_const(mrb, mrb->float_class, "MIN_10_EXP",   mrb_fixnum_value(MRB_FLT_MIN_10_EXP));
+  mrb_define_const(mrb, mrb->float_class, "MAX_EXP",      mrb_fixnum_value(MRB_FLT_MAX_EXP));
+  mrb_define_const(mrb, mrb->float_class, "MAX",          mrb_float_value(mrb, MRB_FLT_MAX));
+  mrb_define_const(mrb, mrb->float_class, "MAX_10_EXP",   mrb_fixnum_value(MRB_FLT_MAX_10_EXP));
+#endif /* MRB_WITHOUT_FLOAT */
 }
 
 void
index c85cb61..efdf25a 100644 (file)
@@ -1,14 +1,6 @@
 ##
 # Numeric(Ext) Test
 
-assert('Integer#chr') do
-  assert_equal("A", 65.chr)
-  assert_equal("B", 0x42.chr)
-
-  # multibyte encoding (not support yet)
-  assert_raise(RangeError) { 256.chr }
-end
-
 assert('Integer#div') do
   assert_equal 52, 365.div(7)
 end
index 6d14b4a..1aea2c8 100644 (file)
@@ -1,5 +1,5 @@
 MRuby::Gem::Specification.new('mruby-object-ext') do |spec|
   spec.license = 'MIT'
   spec.author  = 'mruby developers'
-  spec.summary = 'Object class extension'
+  spec.summary = 'extensional methods shared by all objects'
 end
index 581156c..f014df4 100644 (file)
@@ -1,4 +1,18 @@
-class Object
+module Kernel
+  # call-seq:
+  #   obj.yield_self {|_obj|...} -> an_object
+  #   obj.then {|_obj|...}       -> an_object
+  #
+  # Yields <i>obj</i> and returns the result.
+  #
+  #   'my string'.yield_self {|s|s.upcase} #=> "MY STRING"
+  #
+  def yield_self(&block)
+    return to_enum :yield_self unless block
+    block.call(self)
+  end
+  alias then yield_self
+
   ##
   #  call-seq:
   #     obj.tap{|x|...}    -> obj
index b076b3e..31bb689 100644 (file)
@@ -1,6 +1,7 @@
 #include <mruby.h>
 #include <mruby/array.h>
 #include <mruby/class.h>
+#include <mruby/hash.h>
 #include <mruby/proc.h>
 
 /*
@@ -33,6 +34,19 @@ nil_to_f(mrb_state *mrb, mrb_value obj)
 
 /*
  *  call-seq:
+ *     nil.to_h    -> {}
+ *
+ *  Always returns an empty hash.
+ */
+
+static mrb_value
+nil_to_h(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_hash_new(mrb);
+}
+
+/*
+ *  call-seq:
  *     nil.to_i    -> 0
  *
  *  Always returns zero.
@@ -46,6 +60,22 @@ nil_to_i(mrb_state *mrb, mrb_value obj)
 
 /*
  *  call-seq:
+ *     obj.itself -> an_object
+ *
+ *  Returns <i>obj</i>.
+ *
+ *      string = 'my string' #=> "my string"
+ *      string.itself.object_id == string.object_id #=> true
+ *
+ */
+static mrb_value
+mrb_f_itself(mrb_state *mrb, mrb_value self)
+{
+  return self;
+}
+
+/*
+ *  call-seq:
  *     obj.instance_exec(arg...) {|var...| block }                       -> obj
  *
  *  Executes the given block within the context of the receiver
@@ -70,23 +100,10 @@ mrb_obj_instance_exec(mrb_state *mrb, mrb_value self)
   mrb_value blk;
   struct RClass *c;
 
-  mrb_get_args(mrb, "*&", &argv, &argc, &blk);
-
-  if (mrb_nil_p(blk)) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
-  }
-
-  switch (mrb_type(self)) {
-  case MRB_TT_SYMBOL:
-  case MRB_TT_FIXNUM:
-#ifndef MRB_WITHOUT_FLOAT
-  case MRB_TT_FLOAT:
-#endif
-    c = NULL;
-    break;
-  default:
-    c = mrb_class_ptr(mrb_singleton_class(mrb, self));
-    break;
+  mrb_get_args(mrb, "*&!", &argv, &argc, &blk);
+  c = mrb_singleton_class_ptr(mrb, self);
+  if (mrb->c->ci->acc < 0) {
+    return mrb_yield_with_class(mrb, blk, argc, argv, self, c);
   }
   mrb->c->ci->target_class = c;
   return mrb_yield_cont(mrb, blk, self, argc, argv);
@@ -101,9 +118,12 @@ mrb_mruby_object_ext_gem_init(mrb_state* mrb)
 #ifndef MRB_WITHOUT_FLOAT
   mrb_define_method(mrb, n, "to_f", nil_to_f,       MRB_ARGS_NONE());
 #endif
+  mrb_define_method(mrb, n, "to_h", nil_to_h,       MRB_ARGS_NONE());
   mrb_define_method(mrb, n, "to_i", nil_to_i,       MRB_ARGS_NONE());
 
-  mrb_define_method(mrb, mrb->kernel_module, "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK());
+  mrb_define_method(mrb, mrb->kernel_module, "itself", mrb_f_itself, MRB_ARGS_NONE());
+
+  mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK());
 }
 
 void
index fbff206..9975e78 100644 (file)
@@ -7,6 +7,10 @@ assert('NilClass#to_f') do
   assert_equal 0.0, nil.to_f
 end
 
+assert('NilClass#to_h') do
+  assert_equal Hash.new, nil.to_h
+end
+
 assert('NilClass#to_i') do
   assert_equal 0, nil.to_i
 end
index b31dee0..b89fb05 100644 (file)
@@ -89,7 +89,6 @@ os_count_objects(mrb_state *mrb, mrb_value self)
       COUNT_TYPE(T_STRING);
       COUNT_TYPE(T_RANGE);
       COUNT_TYPE(T_EXCEPTION);
-      COUNT_TYPE(T_FILE);
       COUNT_TYPE(T_ENV);
       COUNT_TYPE(T_DATA);
       COUNT_TYPE(T_FIBER);
@@ -161,11 +160,7 @@ os_each_object(mrb_state *mrb, mrb_value self)
 {
   mrb_value cls = mrb_nil_value();
   struct os_each_object_data d;
-  mrb_get_args(mrb, "&|C", &d.block, &cls);
-
-  if (mrb_nil_p(d.block)) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "Expected block in ObjectSpace.each_object.");
-  }
+  mrb_get_args(mrb, "&!|C", &d.block, &cls);
 
   d.target_module = mrb_nil_p(cls) ? NULL : mrb_class_ptr(cls);
   d.count = 0;
index 8db89ee..9c44c21 100644 (file)
@@ -56,5 +56,5 @@ assert('ObjectSpace.each_object') do
 end
 
 assert 'Check class pointer of ObjectSpace.each_object.' do
-  ObjectSpace.each_object { |obj| !obj }
+  assert_nothing_raised { ObjectSpace.each_object { |obj| !obj } }
 end
diff --git a/third-party/mruby/mrbgems/mruby-pack/.gitignore b/third-party/mruby/mrbgems/mruby-pack/.gitignore
deleted file mode 100644 (file)
index 55ef316..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-gem_*
-gem-*
-mrb-*.a
-src/*.o
-/tmp
diff --git a/third-party/mruby/mrbgems/mruby-pack/.travis.yml b/third-party/mruby/mrbgems/mruby-pack/.travis.yml
deleted file mode 100644 (file)
index ffe2272..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-script:
-  - "ruby run_test.rb all test"
index 95733e2..c8a653f 100644 (file)
@@ -49,6 +49,7 @@ There is no dependency on other mrbgems.
 ## License
 
 Copyright (c) 2012 Internet Initiative Japan Inc.
+Copyright (c) 2017 mruby developers
 
 Permission is hereby granted, free of charge, to any person obtaining a 
 copy of this software and associated documentation files (the "Software"), 
index 6e8375d..f1c0306 100644 (file)
@@ -1,6 +1,6 @@
 MRuby::Gem::Specification.new('mruby-pack') do |spec|
   spec.license = 'MIT'
-  spec.authors = 'Internet Initiative Japan Inc.'
+  spec.authors = ['Internet Initiative Japan Inc.', 'mruby developers']
   spec.summary = 'Array#pack and String#unpack method'
 
   spec.cc.include_paths << "#{build.root}/src"
diff --git a/third-party/mruby/mrbgems/mruby-pack/packtest.rb b/third-party/mruby/mrbgems/mruby-pack/packtest.rb
deleted file mode 100644 (file)
index 459447a..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-# encoding: ascii
-
-# a = Array, s = String, t = Template
-
-def packtest(a, s, t)
-  begin
-    r = a.pack(t)
-    return if r == s
-    puts "#{a.inspect}.pack(#{t.inspect}) -> #{r.inspect} should be #{s.inspect}"
-  rescue => r
-    unless r.is_a? s
-      puts "#{a.inspect}.pack(#{t.inspect}) -> #{r.inspect} should be #{s.inspect}"
-    end
-  end
-end
-
-def unpacktest(a, s, t)
-  r = s.unpack(t)
-  return if r == a
-  puts "#{s.inspect}.unpack(#{t.inspect}) -> #{r.inspect} should be #{a.inspect}"
-end
-
-def pptest(a, s, t)
-  packtest(a, s, t)
-  unpacktest(a, s, t)
-end
-
-pptest [1], "\x01", "C"
-
-packtest [1.1], "\x01", "C"
-packtest [-1], "\xff", "C"
-packtest [1,2], "\x01\x02", "C2"
-#packtest [1], "X", ArgumentError
-
-unpacktest [48, nil], "0", "CC"
-unpacktest [160, -96], "\xa0\xa0", "Cc"
-unpacktest [49, 50, 51], "123", "C*"
-
-pptest [12849], "12", "S"
-unpacktest [nil], "0", "S"
-unpacktest [12849, nil], "123", "SS"
-unpacktest [12849], "123", "S*"
-
-pptest [10000], "\x27\x10", "s>"
-pptest [-10000], "\xd8\xf0", "s>"
-pptest [50000], "\xc3\x50", "S>"
-
-pptest [10000], "\x10\x27", "s<"
-pptest [-10000], "\xf0\xd8", "s<"
-pptest [50000], "\x50\xc3", "S<"
-
-pptest [1000000000], "\x3b\x9a\xca\x00", "l>"
-pptest [-1000000000], "\xc4\x65\x36\x00", "l>"
-
-pptest [1], "\x01\x00\x00\x00", "L<"
-pptest [258], "\x02\x01\x00\x00", "L<"
-pptest [66051], "\x03\x02\x01\x00", "L<"
-pptest [16909060], "\x04\x03\x02\x01", "L<"
-pptest [16909060], "\x01\x02\x03\x04", "L>"
-
-packtest [-1], "\xff\xff\xff\xff", "L<"
-
-pptest [1000000000], "\x00\x00\x00\x00\x3b\x9a\xca\x00", "q>"
-pptest [-1000000000], "\xff\xff\xff\xff\xc4\x65\x36\x00", "q>"
-
-if (2**33).is_a? Fixnum
-  pptest [81985529216486895],    "\x01\x23\x45\x67\x89\xab\xcd\xef", "q>"
-  pptest [-1167088121787636991], "\x01\x23\x45\x67\x89\xab\xcd\xef", "q<"
-end
-
-pptest [16909060], "\x01\x02\x03\x04", "N"
-pptest [258], "\x01\x02", "n"
-pptest [32769], "\x80\x01", "n"
-
-pptest [16909060], "\x04\x03\x02\x01", "V"
-pptest [258], "\x02\x01", "v"
-
-packtest [""], "", "m"
-packtest ["a"], "YQ==\n", "m"
-packtest ["ab"], "YWI=\n", "m"
-packtest ["abc"], "YWJj\n", "m"
-packtest ["abcd"], "YWJjZA==\n", "m"
-
-unpacktest [""], "", "m"
-unpacktest ["a"], "YQ==\n", "m"
-unpacktest ["ab"], "YWI=\n", "m"
-unpacktest ["abc"], "YWJj\n", "m"
-unpacktest ["abcd"], "YWJjZA==\n", "m"
-
-packtest [""], "\0", "H"
-packtest ["3"], "0", "H"
-packtest ["34"], "", "H0"
-packtest ["34"], "0", "H"
-packtest ["34"], "4", "H2"
-packtest ["34"], "4\0", "H3"
-packtest ["3456"], "4P", "H3"
-packtest ["34563"], "4V0", "H*"
-packtest ["5a"], "Z", "H*"
-packtest ["5A"], "Z", "H*"
-
-unpacktest [""], "", "H"
-unpacktest [""], "0", "H0"
-unpacktest ["3"], "0", "H"
-unpacktest ["30"], "0", "H2"
-unpacktest ["30"], "0", "H3"
-unpacktest ["303"], "01", "H3"
-unpacktest ["303132"], "012", "H*"
-unpacktest ["3031", 50], "012", "H4C"
-unpacktest ["5a"], "Z", "H*"
-
-packtest [""], "\0", "h"
-packtest ["3"], "\03", "h"
-packtest ["34"], "", "h0"
-packtest ["34"], "\03", "h"
-packtest ["34"], "C", "h2"
-packtest ["34"], "C\0", "h3"
-packtest ["3456"], "C\05", "h3"
-packtest ["34563"], "Ce\03", "h*"
-
-packtest   [""],    " ",   "A"
-unpacktest [""],    "",    "A"
-pptest     ["1"],   "1",   "A"
-pptest     ["1"],   "1 ",  "A2"
-unpacktest ["1"],   "1",   "A2"
-unpacktest ["1"],   "1 ",  "A2"
-unpacktest ["1"],   "1\0", "A2"
-packtest   ["12"],  "1",   "A"
-unpacktest ["1"],   "12",  "A"
-pptest     ["123"], "123", "A*"
-packtest   ["1","2"], "2", "A0A"
-unpacktest ["","2"],  "2", "A0A"
-
-packtest   [""],    "\0",  "a"
-unpacktest [""],    "",    "a"
-pptest     ["1"],   "1",   "a"
-pptest     ["1 "],  "1 ",  "a2"
-pptest     ["1\0"], "1\0", "a2"
-packtest   ["1"],   "1\0", "a2"
-pptest     ["123"], "123", "a*"
-
-packtest   [""],    "\0",    "Z"
-unpacktest [""],    "",      "Z"
-pptest     ["1"],   "1",     "Z"
-pptest     ["1"],   "1\0",   "Z2"
-pptest     ["1 "],  "1 ",    "Z2"
-pptest     ["123"], "123\0", "Z*"
-pptest     ["1","2"], "12",      "ZZ"
-pptest     ["1","2"], "1\0002",  "Z*Z"
-unpacktest ["1","3"], "1\00023", "Z3Z"
-
-packtest   [1, 2], "\x01\x02", "CyC"
-
-packtest   [65], "A", 'U'
-packtest   [59411], "\xEE\xA0\x93", 'U'
-
-pptest     [1], "\x00\x01", "xC"
-unpacktest [2], "\xcc\x02", "xC"
diff --git a/third-party/mruby/mrbgems/mruby-pack/run_test.rb b/third-party/mruby/mrbgems/mruby-pack/run_test.rb
deleted file mode 100644 (file)
index d9566a2..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env ruby
-#
-# mrbgems test runner
-#
-
-gemname = File.basename(File.dirname(File.expand_path __FILE__))
-
-if __FILE__ == $0
-  repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
-  build_args = ARGV
-  build_args = ['all', 'test']  if build_args.nil? or build_args.empty?
-
-  Dir.mkdir 'tmp'  unless File.exist?('tmp')
-  unless File.exist?(dir)
-    system "git clone #{repository} #{dir}"
-  end
-
-  exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
-end
-
-MRuby::Build.new do |conf|
-  toolchain :gcc
-  conf.gembox 'default'
-
-  conf.gem File.expand_path(File.dirname(__FILE__))
-end
index ac29fdb..3a2c336 100644 (file)
@@ -2,8 +2,8 @@
  ** pack.c - Array#pack, String#unpack
  */
 
-#include "mruby.h"
-#include "error.h"
+#include <mruby.h>
+#include "mruby/error.h"
 #include "mruby/array.h"
 #include "mruby/class.h"
 #include "mruby/numeric.h"
@@ -13,7 +13,6 @@
 #include <ctype.h>
 #include <errno.h>
 #include <limits.h>
-#include <stdio.h>
 #include <string.h>
 
 struct tmpl {
@@ -118,9 +117,9 @@ make_base64_dec_tab(void)
     base64_dec_tab['a' + i] = i + 26;
   for (i = 0; i < 10; i++)
     base64_dec_tab['0' + i] = i + 52;
-  base64_dec_tab['+'] = 62;
-  base64_dec_tab['/'] = 63;
-  base64_dec_tab['='] = PACK_BASE64_PADDING;
+  base64_dec_tab['+'+0] = 62;
+  base64_dec_tab['/'+0] = 63;
+  base64_dec_tab['='+0] = PACK_BASE64_PADDING;
 }
 
 static mrb_value
@@ -213,6 +212,59 @@ pack_l(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int fl
   return 4;
 }
 
+#ifndef MRB_INT64
+static void
+u32tostr(char *buf, size_t len, uint32_t n)
+{
+#ifdef MRB_DISABLE_STDIO
+  char *bufend = buf + len;
+  char *p = bufend - 1;
+
+  if (len < 1) {
+    return;
+  }
+
+  *p -- = '\0';
+  len --;
+
+  if (n > 0) {
+    for (; len > 0 && n > 0; len --, n /= 10) {
+      *p -- = '0' + (n % 10);
+    }
+    p ++;
+  }
+  else if (len > 0) {
+    *p = '0';
+    len --;
+  }
+
+  memmove(buf, p, bufend - p);
+#else
+  snprintf(buf, len, "%" PRIu32, n);
+#endif /* MRB_DISABLE_STDIO */
+}
+
+static void
+i32tostr(char *buf, size_t len, int32_t n)
+{
+#ifdef MRB_DISABLE_STDIO
+  if (len < 1) {
+    return;
+  }
+
+  if (n < 0) {
+    *buf ++ = '-';
+    len --;
+    n = -n;
+  }
+
+  u32tostr(buf, len, (uint32_t)n);
+#else
+  snprintf(buf, len, "%" PRId32, n);
+#endif /* MRB_DISABLE_STDIO */
+}
+#endif /* MRB_INT64 */
+
 static int
 unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags)
 {
@@ -237,16 +289,16 @@ unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un
     int32_t sl = ul;
 #ifndef MRB_INT64
     if (!FIXABLE(sl)) {
-      snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %ld", (long)sl);
-      mrb_raise(mrb, E_RANGE_ERROR, msg);
+      i32tostr(msg, sizeof(msg), sl);
+      mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg);
     }
 #endif
     n = sl;
   } else {
 #ifndef MRB_INT64
     if (!POSFIXABLE(ul)) {
-      snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %lu", (unsigned long)ul);
-      mrb_raise(mrb, E_RANGE_ERROR, msg);
+      u32tostr(msg, sizeof(msg), ul);
+      mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg);
     }
 #endif
     n = ul;
@@ -284,6 +336,57 @@ pack_q(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int fl
   return 8;
 }
 
+static void
+u64tostr(char *buf, size_t len, uint64_t n)
+{
+#ifdef MRB_DISABLE_STDIO
+  char *bufend = buf + len;
+  char *p = bufend - 1;
+
+  if (len < 1) {
+    return;
+  }
+
+  *p -- = '\0';
+  len --;
+
+  if (n > 0) {
+    for (; len > 0 && n > 0; len --, n /= 10) {
+      *p -- = '0' + (n % 10);
+    }
+    p ++;
+  }
+  else if (len > 0) {
+    *p = '0';
+    len --;
+  }
+
+  memmove(buf, p, bufend - p);
+#else
+  snprintf(buf, len, "%" PRIu64, n);
+#endif /* MRB_DISABLE_STDIO */
+}
+
+static void
+i64tostr(char *buf, size_t len, int64_t n)
+{
+#ifdef MRB_DISABLE_STDIO
+  if (len < 1) {
+    return;
+  }
+
+  if (n < 0) {
+    *buf ++ = '-';
+    len --;
+    n = -n;
+  }
+
+  u64tostr(buf, len, (uint64_t)n);
+#else
+  snprintf(buf, len, "%" PRId64, n);
+#endif /* MRB_DISABLE_STDIO */
+}
+
 static int
 unpack_q(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags)
 {
@@ -307,14 +410,14 @@ unpack_q(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un
   if (flags & PACK_FLAG_SIGNED) {
     int64_t sll = ull;
     if (!FIXABLE(sll)) {
-      snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %lld", (long long)sll);
-      mrb_raise(mrb, E_RANGE_ERROR, msg);
+      i64tostr(msg, sizeof(msg), sll);
+      mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg);
     }
     n = sll;
   } else {
     if (!POSFIXABLE(ull)) {
-      snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %llu", (unsigned long long)ull);
-      mrb_raise(mrb, E_RANGE_ERROR, msg);
+      u64tostr(msg, sizeof(msg), ull);
+      mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg);
     }
     n = ull;
   }
@@ -529,8 +632,8 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp)
     mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character");
   }
   if (n > *lenp) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character (expected %S bytes, given %S bytes)",
-               mrb_fixnum_value(n), mrb_fixnum_value(*lenp));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character (expected %d bytes, given %d bytes)",
+               n, *lenp);
   }
   *lenp = n--;
   if (n != 0) {
@@ -976,7 +1079,7 @@ alias:
       case 4: t = 'L'; goto alias;
       case 8: t = 'Q'; goto alias;
       default:
-        mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %S", mrb_fixnum_value(sizeof(int)));
+        mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %d", (int)sizeof(int));
     }
     break;
   case 'i':
@@ -985,7 +1088,7 @@ alias:
       case 4: t = 'l'; goto alias;
       case 8: t = 'q'; goto alias;
       default:
-        mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %S", mrb_fixnum_value(sizeof(int)));
+        mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %d", (int)sizeof(int));
     }
     break;
   case 'L':
@@ -1002,7 +1105,7 @@ alias:
   case 'm':
     dir = PACK_DIR_BASE64;
     type = PACK_TYPE_STRING;
-    flags |= PACK_FLAG_WIDTH;
+    flags |= PACK_FLAG_WIDTH | PACK_FLAG_COUNT2;
     break;
   case 'N':  /* = "L>" */
     dir = PACK_DIR_LONG;
@@ -1075,18 +1178,18 @@ alias:
     if (ISDIGIT(ch)) {
       count = ch - '0';
       while (tmpl->idx < tlen && ISDIGIT(tptr[tmpl->idx])) {
-        count = count * 10 + (tptr[tmpl->idx++] - '0');
-        if (count < 0) {
+        int ch = tptr[tmpl->idx++] - '0';
+        if (count+ch > INT_MAX/10) {
           mrb_raise(mrb, E_RUNTIME_ERROR, "too big template length");
         }
+        count = count * 10 + ch;
       }
       continue;  /* special case */
     } else if (ch == '*')  {
       count = -1;
     } else if (ch == '_' || ch == '!' || ch == '<' || ch == '>') {
       if (strchr("sSiIlLqQ", (int)t) == NULL) {
-        char ch_str = (char)ch;
-        mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%S' allowed only after types sSiIlLqQ", mrb_str_new(mrb, &ch_str, 1));
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%c' allowed only after types sSiIlLqQ", ch);
       }
       if (ch == '_' || ch == '!') {
         flags |= PACK_FLAG_s;
@@ -1155,7 +1258,7 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
 #endif
       else if (type == PACK_TYPE_STRING) {
         if (!mrb_string_p(o)) {
-          mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into String", mrb_class_path(mrb, mrb_obj_class(mrb, o)));
+          mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %T into String", o);
         }
       }
 
@@ -1195,7 +1298,7 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
       default:
         break;
       }
-      if (dir == PACK_DIR_STR) { /* always consumes 1 entry */
+      if (dir == PACK_DIR_STR || dir == PACK_DIR_BASE64) { /* always consumes 1 entry */
         aidx++;
         break;
       }
@@ -1248,6 +1351,9 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single)
       case PACK_DIR_STR:
         srcidx += unpack_a(mrb, sptr, srclen - srcidx, result, count, flags);
         break;
+      case PACK_DIR_BASE64:
+        srcidx += unpack_m(mrb, sptr, srclen - srcidx, result, flags);
+        break;
       }
       continue;
     }
@@ -1274,9 +1380,6 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single)
       case PACK_DIR_QUAD:
         srcidx += unpack_q(mrb, sptr, srclen - srcidx, result, flags);
         break;
-      case PACK_DIR_BASE64:
-        srcidx += unpack_m(mrb, sptr, srclen - srcidx, result, flags);
-        break;
 #ifndef MRB_WITHOUT_FLOAT
       case PACK_DIR_FLOAT:
         srcidx += unpack_float(mrb, sptr, srclen - srcidx, result, flags);
@@ -1298,7 +1401,12 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single)
     if (single) break;
   }
 
-  if (single) return RARRAY_PTR(result)[0];
+  if (single) {
+    if (RARRAY_LEN(result) > 0) {
+      return RARRAY_PTR(result)[0];
+    }
+    return mrb_nil_value();
+  }
   return result;
 }
 
index 1788c2b..6832adc 100644 (file)
+PACK_IS_LITTLE_ENDIAN = "\x01\00".unpack('S')[0] == 0x01
+
+def assert_pack tmpl, packed, unpacked
+  t = tmpl.inspect
+  assert "assert_pack" do
+    assert_equal packed, unpacked.pack(tmpl), "#{unpacked.inspect}.pack(#{t})"
+    assert_equal unpacked, packed.unpack(tmpl), "#{packed.inspect}.unpack(#{t})"
+  end
+end
+
 # pack & unpack 'm' (base64)
 assert('[""].pack("m")') do
-  ary = ""
-  str = ""
-  [ary].pack("m") == str and
-  str.unpack("m") == [ary]
+  assert_pack "m", "", [""]
 end
 
 assert('["\0"].pack("m")') do
-  ary = "\0"
-  str = "AA==\n"
-  [ary].pack("m") == str and
-  str.unpack("m") == [ary]
+  assert_pack "m", "AA==\n", ["\0"]
 end
 
 assert('["\0\0"].pack("m")') do
-  ary = "\0\0"
-  str = "AAA=\n"
-  [ary].pack("m") == str and
-  str.unpack("m") == [ary]
+  assert_pack "m", "AAA=\n", ["\0\0"]
 end
 
 assert('["\0\0\0"].pack("m")') do
-  ary = "\0\0\0"
-  str = "AAAA\n"
-  [ary].pack("m") == str and
-  str.unpack("m") == [ary]
+  assert_pack "m", "AAAA\n", ["\0\0\0"]
 end
 
 assert('["abc..xyzABC..XYZ"].pack("m")') do
-  ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"].pack("m") == "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n"
+  assert_pack "m", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n", ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]
 end
 
 assert('"YWJ...".unpack("m") should "abc..xyzABC..XYZ"') do
-  str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
-  "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n".unpack("m") == [str] and
-  "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==\n".unpack("m") == [str]
+  ary = ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]
+  assert_equal ary, "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n".unpack("m")
+  assert_equal ary, "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==\n".unpack("m")
+end
+
+assert('["A", "B"].pack') do
+  assert_equal "QQ==\n", ["A", "B"].pack("m50")
+  assert_equal ["A"], "QQ==\n".unpack("m50")
+  assert_equal "QQ==Qg==", ["A", "B"].pack("m0 m0")
+  assert_equal ["A", "B"], "QQ==Qg==".unpack("m10 m10")
+end
+
+assert('["abc..xyzABC..XYZ"].pack("m0")') do
+  assert_pack "m0", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==", ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]
 end
 
 # pack & unpack 'H'
 assert('["3031"].pack("H*")') do
-  ary = "3031"
-  str = "01"
-  [ary].pack("H*") == str and
-  str.unpack("H*") == [ary]
+  assert_pack "H*", "01", ["3031"]
 end
 
 assert('["10"].pack("H*")') do
-  ary = "10"
-  str = "\020"
-  [ary].pack("H*") == str and
-  str.unpack("H*") == [ary]
+  assert_pack "H*", "\020", ["10"]
 end
 
 assert('[0,1,127,128,255].pack("C*")') do
- ary = [ 0, 1, 127, 128, 255 ]
- str = "\x00\x01\x7F\x80\xFF"
- ary.pack("C*") == str and str.unpack("C*") == ary
+  assert_pack "C*", "\x00\x01\x7F\x80\xFF", [0, 1, 127, 128, 255]
 end
 
 # pack "a"
 assert('["abc"].pack("a")') do
-  ["abc"].pack("a") == "a" and
-  ["abc"].pack("a*") == "abc" and
-  ["abc"].pack("a4") == "abc\0"
+  assert_equal "a", ["abc"].pack("a")
+  assert_equal "abc", ["abc"].pack("a*")
+  assert_equal "abc\0", ["abc"].pack("a4")
 end
 
 # upack "a"
 assert('["abc"].pack("a")') do
-  "abc\0".unpack("a4") == ["abc\0"] and
-  "abc ".unpack("a4") == ["abc "]
+  assert_equal ["abc\0"], "abc\0".unpack("a4")
+  assert_equal ["abc "], "abc ".unpack("a4")
 end
 
 # pack "A"
 assert('["abc"].pack("A")') do
-  ["abc"].pack("A") == "a" and
-  ["abc"].pack("A*") == "abc" and
-  ["abc"].pack("A4") == "abc "
+  assert_equal "a", ["abc"].pack("A")
+  assert_equal "abc", ["abc"].pack("A*")
+  assert_equal "abc ", ["abc"].pack("A4")
 end
 
 # upack "A"
 assert('["abc"].pack("A")') do
-  "abc\0".unpack("A4") == ["abc"] and
-  "abc ".unpack("A4") == ["abc"]
+  assert_equal ["abc"], "abc\0".unpack("A4")
+  assert_equal ["abc"], "abc ".unpack("A4")
 end
 
 # regression tests
 assert('issue #1') do
-  [1, 2].pack("nn") == "\000\001\000\002"
+  assert_equal "\000\001\000\002", [1, 2].pack("nn")
 end
 
-def assert_pack tmpl, packed, unpacked
-  assert_equal packed, unpacked.pack(tmpl)
-  assert_equal unpacked, packed.unpack(tmpl)
-end
-
-PACK_IS_LITTLE_ENDIAN = "\x01\00".unpack('S')[0] == 0x01
-
 assert 'pack float' do
   assert_pack 'e', "\x00\x00@@", [3.0]
   assert_pack 'g', "@@\x00\x00", [3.0]
index 27567d8..cfe14a5 100644 (file)
@@ -48,14 +48,8 @@ module Kernel
     args.__svalue
   end
 
-  unless Kernel.respond_to?(:sprintf)
-    def printf(*args)
-      raise NotImplementedError.new('printf not available')
-    end
-  else
-    def printf(*args)
-      __printstr__(sprintf(*args))
-      nil
-    end
+  def printf(*args)
+    __printstr__(sprintf(*args))
+    nil
   end
 end
index f7f99fc..9301dbe 100644 (file)
@@ -1,6 +1,10 @@
 #include <mruby.h>
+
+#ifdef MRB_DISABLE_STDIO
+# error print conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
+#endif
+
 #include <mruby/string.h>
-#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #if defined(_WIN32)
@@ -41,9 +45,8 @@ printstr(mrb_state *mrb, mrb_value obj)
 mrb_value
 mrb_printstr(mrb_state *mrb, mrb_value self)
 {
-  mrb_value argv;
+  mrb_value argv = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &argv);
   printstr(mrb, argv);
 
   return argv;
index 17884e3..5343c47 100644 (file)
@@ -6,7 +6,7 @@
 #include <mruby/debug.h>
 
 static mrb_value
-mrb_proc_lambda(mrb_state *mrb, mrb_value self)
+mrb_proc_lambda_p(mrb_state *mrb, mrb_value self)
 {
   struct RProc *p = mrb_proc_ptr(self);
   return mrb_bool_value(MRB_PROC_STRICT_P(p));
@@ -38,7 +38,7 @@ mrb_proc_inspect(mrb_state *mrb, mrb_value self)
 {
   struct RProc *p = mrb_proc_ptr(self);
   mrb_value str = mrb_str_new_lit(mrb, "#<Proc:");
-  mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self)));
+  mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self)));
 
   if (!MRB_PROC_CFUNC_P(p)) {
     mrb_irep *irep = p->body.irep;
@@ -52,7 +52,7 @@ mrb_proc_inspect(mrb_state *mrb, mrb_value self)
 
     line = mrb_debug_get_line(mrb, irep, 0);
     if (line != -1) {
-      str = mrb_format(mrb, "%S:%S", str, mrb_fixnum_value(line));
+      mrb_str_concat(mrb, str, mrb_fixnum_value(line));
     }
     else {
       mrb_str_cat_lit(mrb, str, "-");
@@ -72,10 +72,7 @@ mrb_kernel_proc(mrb_state *mrb, mrb_value self)
 {
   mrb_value blk;
 
-  mrb_get_args(mrb, "&", &blk);
-  if (mrb_nil_p(blk)) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
-  }
+  mrb_get_args(mrb, "&!", &blk);
 
   return blk;
 }
@@ -153,7 +150,7 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self)
       mrb_ary_push(mrb, a, sname);
       if (i < max && irep->lv[i].name) {
         mrb_sym sym = irep->lv[i].name;
-        const char *name = mrb_sym2name(mrb, sym);
+        const char *name = mrb_sym_name(mrb, sym);
         switch (name[0]) {
         case '*': case '&':
           break;
@@ -172,14 +169,14 @@ void
 mrb_mruby_proc_ext_gem_init(mrb_state* mrb)
 {
   struct RClass *p = mrb->proc_class;
-  mrb_define_method(mrb, p, "lambda?",         mrb_proc_lambda,          MRB_ARGS_NONE());
+  mrb_define_method(mrb, p, "lambda?",         mrb_proc_lambda_p,        MRB_ARGS_NONE());
   mrb_define_method(mrb, p, "source_location", mrb_proc_source_location, MRB_ARGS_NONE());
   mrb_define_method(mrb, p, "to_s",            mrb_proc_inspect,         MRB_ARGS_NONE());
   mrb_define_method(mrb, p, "inspect",         mrb_proc_inspect,         MRB_ARGS_NONE());
   mrb_define_method(mrb, p, "parameters",      mrb_proc_parameters,      MRB_ARGS_NONE());
 
-  mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE());
-  mrb_define_method(mrb, mrb->kernel_module,       "proc", mrb_kernel_proc, MRB_ARGS_NONE());
+  mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
+  mrb_define_method(mrb, mrb->kernel_module,       "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
 }
 
 void
index 1220841..a6321d3 100644 (file)
@@ -1,16 +1,32 @@
 ##
 # Proc(Ext) Test
 
+def enable_debug_info?
+  return @enable_debug_info unless @enable_debug_info == nil
+  begin
+    raise
+  rescue => e
+    @enable_debug_info = !e.backtrace.empty?
+  end
+end
+
 assert('Proc#source_location') do
-  loc = Proc.new {}.source_location
-  next true if loc.nil?
-  assert_equal loc[0][-7, 7], 'proc.rb'
-  assert_equal loc[1], 5
+  skip unless enable_debug_info?
+  file, line = Proc.new{}.source_location
+  assert_equal __FILE__, file
+  assert_equal __LINE__ - 2, line
 end
 
 assert('Proc#inspect') do
   ins = Proc.new{}.inspect
-  assert_kind_of String, ins
+  if enable_debug_info?
+    metas = %w(\\ * ? [ ] { })
+    file = __FILE__.split("").map{|c| metas.include?(c) ? "\\#{c}" : c}.join
+    line = __LINE__ - 4
+  else
+    file = line = "-"
+  end
+  assert_match "#<Proc:0x*@#{file}:#{line}>", ins
 end
 
 assert('Proc#parameters') do
diff --git a/third-party/mruby/mrbgems/mruby-random/src/mt19937ar.c b/third-party/mruby/mrbgems/mruby-random/src/mt19937ar.c
deleted file mode 100644 (file)
index 405bd5c..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
-** mt19937ar.c - MT Random functions
-**
-** Copyright (C) 1997 - 2016, Makoto Matsumoto and Takuji Nishimura,
-** All rights reserved.
-**
-** 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.
-**
-** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
-**
-** Any feedback is very welcome.
-** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
-** email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
-**
-** This version is modified by mruby developers. If you see any problem,
-** contact us first at https://github.com/mruby/mruby/issues
-*/
-
-#include <mruby.h>
-#include "mt19937ar.h"
-
-/* Period parameters */
-/* #define N 624 */
-#define M 397
-#define MATRIX_A 0x9908b0dfUL   /* constant vector a */
-#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
-#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
-
-#if 0 /* dead_code */
-static unsigned long mt[N]; /* the array for the state vector  */
-static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
-#endif /* dead_code */
-
-void mrb_random_init_genrand(mt_state *t, unsigned long s)
-{
-    t->mt[0]= s & 0xffffffffUL;
-    for (t->mti=1; t->mti<N; t->mti++) {
-        t->mt[t->mti] = (1812433253UL * (t->mt[t->mti-1] ^ (t->mt[t->mti-1] >> 30)) + t->mti);
-        t->mt[t->mti] &= 0xffffffffUL;
-    }
-}
-
-unsigned long mrb_random_genrand_int32(mt_state *t)
-{
-    unsigned long y;
-    static const unsigned long mag01[2]={0x0UL, MATRIX_A};
-    /* mag01[x] = x * MATRIX_A  for x=0,1 */
-
-    if (t->mti >= N) { /* generate N words at one time */
-        int kk;
-
-        if (t->mti == N+1)   /* if init_genrand() has not been called, */
-            mrb_random_init_genrand(t, 5489UL); /* a default initial seed is used */
-
-        for (kk=0;kk<N-M;kk++) {
-            y = (t->mt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK);
-            t->mt[kk] = t->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
-        }
-        for (;kk<N-1;kk++) {
-            y = (t->mt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK);
-            t->mt[kk] = t->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
-        }
-        y = (t->mt[N-1]&UPPER_MASK)|(t->mt[0]&LOWER_MASK);
-        t->mt[N-1] = t->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
-
-        t->mti = 0;
-    }
-
-    y = t->mt[t->mti++];
-
-    /* Tempering */
-    y ^= (y >> 11);
-    y ^= (y << 7) & 0x9d2c5680UL;
-    y ^= (y << 15) & 0xefc60000UL;
-    y ^= (y >> 18);
-
-    t->gen.int_ = y;
-
-    return y;
-}
-
-double mrb_random_genrand_real1(mt_state *t)
-{
-    mrb_random_genrand_int32(t);
-    t->gen.double_ =  t->gen.int_*(1.0/4294967295.0);
-    return t->gen.double_;
-    /* divided by 2^32-1 */
-}
-
-#if 0 /* dead_code */
-/* initializes mt[N] with a seed */
-void init_genrand(unsigned long s)
-{
-    mt[0]= s & 0xffffffffUL;
-    for (mti=1; mti<N; mti++) {
-        mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
-        /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
-        /* In the previous versions, MSBs of the seed affect   */
-        /* only MSBs of the array mt[].                        */
-        /* 2002/01/09 modified by Makoto Matsumoto             */
-        mt[mti] &= 0xffffffffUL;
-        /* for >32 bit machines */
-    }
-}
-
-/* initialize by an array with array-length */
-/* init_key is the array for initializing keys */
-/* key_length is its length */
-/* slight change for C++, 2004/2/26 */
-void init_by_array(unsigned long init_key[], int key_length)
-{
-    int i, j, k;
-    init_genrand(19650218UL);
-    i=1; j=0;
-    k = (N>key_length ? N : key_length);
-    for (; k; k--) {
-        mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
-          + init_key[j] + j; /* non linear */
-        mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
-        i++; j++;
-        if (i>=N) { mt[0] = mt[N-1]; i=1; }
-        if (j>=key_length) j=0;
-    }
-    for (k=N-1; k; k--) {
-        mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
-          - i; /* non linear */
-        mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
-        i++;
-        if (i>=N) { mt[0] = mt[N-1]; i=1; }
-    }
-
-    mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
-}
-
-/* generates a random number on [0,0xffffffff]-interval */
-unsigned long genrand_int32(void)
-{
-    unsigned long y;
-    static const unsigned long mag01[2]={0x0UL, MATRIX_A};
-    /* mag01[x] = x * MATRIX_A  for x=0,1 */
-
-    if (mti >= N) { /* generate N words at one time */
-        int kk;
-
-        if (mti == N+1)   /* if init_genrand() has not been called, */
-            init_genrand(5489UL); /* a default initial seed is used */
-
-        for (kk=0;kk<N-M;kk++) {
-            y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
-            mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
-        }
-        for (;kk<N-1;kk++) {
-            y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
-            mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
-        }
-        y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
-        mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
-
-        mti = 0;
-    }
-
-    y = mt[mti++];
-
-    /* Tempering */
-    y ^= (y >> 11);
-    y ^= (y << 7) & 0x9d2c5680UL;
-    y ^= (y << 15) & 0xefc60000UL;
-    y ^= (y >> 18);
-
-    return y;
-}
-
-/* generates a random number on [0,0x7fffffff]-interval */
-long genrand_int31(void)
-{
-    return (long)(genrand_int32()>>1);
-}
-
-/* generates a random number on [0,1]-real-interval */
-double genrand_real1(void)
-{
-    return genrand_int32()*(1.0/4294967295.0);
-    /* divided by 2^32-1 */
-}
-
-/* generates a random number on [0,1)-real-interval */
-double genrand_real2(void)
-{
-    return genrand_int32()*(1.0/4294967296.0);
-    /* divided by 2^32 */
-}
-
-/* generates a random number on (0,1)-real-interval */
-double genrand_real3(void)
-{
-    return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0);
-    /* divided by 2^32 */
-}
-
-/* generates a random number on [0,1) with 53-bit resolution*/
-double genrand_res53(void)
-{
-    unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
-    return(a*67108864.0+b)*(1.0/9007199254740992.0);
-}
-/* These real versions are due to Isaku Wada, 2002/01/09 added */
-#endif /* dead_code */
diff --git a/third-party/mruby/mrbgems/mruby-random/src/mt19937ar.h b/third-party/mruby/mrbgems/mruby-random/src/mt19937ar.h
deleted file mode 100644 (file)
index 7d38232..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-** mt19937ar.h - MT Random functions
-**
-** Copyright (C) 1997 - 2016, Makoto Matsumoto and Takuji Nishimura,
-** All rights reserved.
-**
-** 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.
-**
-** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
-**
-** Any feedback is very welcome.
-** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
-** email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
-**
-** This version is modified by mruby developers. If you see any problem,
-** contact us first at https://github.com/mruby/mruby/issues
-*/
-
-#define N 624
-
-typedef struct {
-  unsigned long mt[N];
-  int mti;
-  union {
-    unsigned long int_;
-    double double_;
-  } gen;
-
-  mrb_int seed;
-  mrb_bool has_seed : 1;
-} mt_state;
-
-void mrb_random_init_genrand(mt_state *, unsigned long);
-unsigned long mrb_random_genrand_int32(mt_state *);
-double mrb_random_genrand_real1(mt_state *t);
-
-/* initializes mt[N] with a seed */
-void init_genrand(unsigned long s);
-
-/* initialize by an array with array-length */
-/* init_key is the array for initializing keys */
-/* key_length is its length */
-/* slight change for C++, 2004/2/26 */
-void init_by_array(unsigned long init_key[], int key_length);
-
-/* generates a random number on [0,0xffffffff]-interval */
-unsigned long genrand_int32(void);
-
-/* generates a random number on [0,0x7fffffff]-interval */
-long genrand_int31(void);
-
-/* These real versions are due to Isaku Wada, 2002/01/09 added */
-/* generates a random number on [0,1]-real-interval */
-double genrand_real1(void);
-
-/* generates a random number on [0,1)-real-interval */
-double genrand_real2(void);
-
-/* generates a random number on (0,1)-real-interval */
-double genrand_real3(void);
-
-/* generates a random number on [0,1) with 53-bit resolution*/
-double genrand_res53(void);
index 6820984..515c070 100644 (file)
 #include <mruby/class.h>
 #include <mruby/data.h>
 #include <mruby/array.h>
-#include "mt19937ar.h"
+#include <mruby/istruct.h>
+#if INT32_MAX <= INTPTR_MAX
+# define XORSHIFT96
+# define NSEEDS 3
+#else
+# define NSEEDS 4
+#endif
+#define LASTSEED (NSEEDS-1)
 
 #include <time.h>
 
-static char const MT_STATE_KEY[] = "$mrb_i_mt_state";
-
-static const struct mrb_data_type mt_state_type = {
-  MT_STATE_KEY, mrb_free,
-};
-
-static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self);
-static mrb_value mrb_random_srand(mrb_state *mrb, mrb_value self);
+typedef struct rand_state {
+  uint32_t seed[NSEEDS];
+} rand_state;
 
 static void
-mt_srand(mt_state *t, unsigned long seed)
+rand_init(rand_state *t)
 {
-  mrb_random_init_genrand(t, seed);
+  t->seed[0] = 123456789;
+  t->seed[1] = 362436069;
+  t->seed[2] = 521288629;
+#ifndef XORSHIFT96
+  t->seed[3] = 88675123;
+#endif
 }
 
-static unsigned long
-mt_rand(mt_state *t)
+static uint32_t
+rand_seed(rand_state *t, uint32_t seed)
 {
-  return mrb_random_genrand_int32(t);
+  uint32_t old_seed = t->seed[LASTSEED];
+  rand_init(t);
+  t->seed[LASTSEED] = seed;
+  return old_seed;
 }
 
-static double
-mt_rand_real(mt_state *t)
+#ifdef XORSHIFT96
+static uint32_t
+rand_uint32(rand_state *state)
 {
-  return mrb_random_genrand_real1(t);
+  uint32_t *seed = state->seed;
+  uint32_t x = seed[0];
+  uint32_t y = seed[1];
+  uint32_t z = seed[2];
+  uint32_t t;
+
+  t = (x ^ (x << 3)) ^ (y ^ (y >> 19)) ^ (z ^ (z << 6));
+  x = y; y = z; z = t;
+  seed[0] = x;
+  seed[1] = y;
+  seed[2] = z;
+
+  return z;
 }
-
-static mrb_value
-mrb_random_mt_srand(mrb_state *mrb, mt_state *t, mrb_value seed)
+#else  /* XORSHIFT96 */
+static uint32_t
+rand_uint32(rand_state *state)
 {
-  if (mrb_nil_p(seed)) {
-    seed = mrb_fixnum_value((mrb_int)(time(NULL) + mt_rand(t)));
-    if (mrb_fixnum(seed) < 0) {
-      seed = mrb_fixnum_value(0 - mrb_fixnum(seed));
-    }
-  }
-
-  mt_srand(t, (unsigned) mrb_fixnum(seed));
+  uint32_t *seed = state->seed;
+  uint32_t x = seed[0];
+  uint32_t y = seed[1];
+  uint32_t z = seed[2];
+  uint32_t w = seed[3];
+  uint32_t t;
+
+  t = x ^ (x << 11);
+  x = y; y = z; z = w;
+  w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
+  seed[0] = x;
+  seed[1] = y;
+  seed[2] = z;
+  seed[3] = w;
+
+  return w;
+}
+#endif  /* XORSHIFT96 */
 
-  return seed;
+#ifndef MRB_WITHOUT_FLOAT
+static double
+rand_real(rand_state *t)
+{
+  uint32_t x = rand_uint32(t);
+  return x*(1.0/4294967295.0);
 }
+#endif
 
 static mrb_value
-mrb_random_mt_rand(mrb_state *mrb, mt_state *t, mrb_value max)
+random_rand(mrb_state *mrb, rand_state *t, mrb_value max)
 {
   mrb_value value;
 
   if (mrb_fixnum(max) == 0) {
-    value = mrb_float_value(mrb, mt_rand_real(t));
+#ifndef MRB_WITHOUT_FLOAT
+    value = mrb_float_value(mrb, rand_real(t));
+#else
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "Float not supported");
+#endif
   }
   else {
-    value = mrb_fixnum_value(mt_rand(t) % mrb_fixnum(max));
+    value = mrb_fixnum_value(rand_uint32(t) % mrb_fixnum(max));
   }
 
   return value;
@@ -90,106 +133,74 @@ get_opt(mrb_state* mrb)
   return arg;
 }
 
-static mrb_value
-get_random(mrb_state *mrb) {
-  return mrb_const_get(mrb,
-             mrb_obj_value(mrb_class_get(mrb, "Random")),
-             mrb_intern_lit(mrb, "DEFAULT"));
-}
-
-static mt_state *
-get_random_state(mrb_state *mrb)
-{
-  mrb_value random_val = get_random(mrb);
-  return DATA_GET_PTR(mrb, random_val, &mt_state_type, mt_state);
+static void
+random_check(mrb_state *mrb, mrb_value random) {
+  struct RClass *c = mrb_class_get(mrb, "Random");
+  if (!mrb_obj_is_kind_of(mrb, random, c) || !mrb_istruct_p(random)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "Random instance required");
+  }
 }
 
 static mrb_value
-mrb_random_g_rand(mrb_state *mrb, mrb_value self)
-{
-  mrb_value random = get_random(mrb);
-  return mrb_random_rand(mrb, random);
+random_default(mrb_state *mrb) {
+  struct RClass *c = mrb_class_get(mrb, "Random");
+  mrb_value d = mrb_const_get(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, "DEFAULT"));
+  if (!mrb_obj_is_kind_of(mrb, d, c)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "Random::DEFAULT replaced");
+  }
+  return d;
 }
 
-static mrb_value
-mrb_random_g_srand(mrb_state *mrb, mrb_value self)
-{
-  mrb_value random = get_random(mrb);
-  return mrb_random_srand(mrb, random);
-}
+#define random_ptr(v) (rand_state*)mrb_istruct_ptr(v)
+#define random_default_state(mrb) random_ptr(random_default(mrb))
 
 static mrb_value
-mrb_random_init(mrb_state *mrb, mrb_value self)
+random_m_init(mrb_state *mrb, mrb_value self)
 {
   mrb_value seed;
-  mt_state *t;
+  rand_state *t;
 
   seed = get_opt(mrb);
-
   /* avoid memory leaks */
-  t = (mt_state*)DATA_PTR(self);
-  if (t) {
-    mrb_free(mrb, t);
-  }
-  mrb_data_init(self, NULL, &mt_state_type);
-
-  t = (mt_state *)mrb_malloc(mrb, sizeof(mt_state));
-  t->mti = N + 1;
-
-  seed = mrb_random_mt_srand(mrb, t, seed);
+  t = random_ptr(self);
   if (mrb_nil_p(seed)) {
-    t->has_seed = FALSE;
+    rand_init(t);
   }
   else {
-    mrb_assert(mrb_fixnum_p(seed));
-    t->has_seed = TRUE;
-    t->seed = mrb_fixnum(seed);
+    rand_seed(t, (uint32_t)mrb_fixnum(seed));
   }
 
-  mrb_data_init(self, t, &mt_state_type);
-
   return self;
 }
 
-static void
-mrb_random_rand_seed(mrb_state *mrb, mt_state *t)
-{
-  if (!t->has_seed) {
-    mrb_random_mt_srand(mrb, t, mrb_nil_value());
-  }
-}
-
 static mrb_value
-mrb_random_rand(mrb_state *mrb, mrb_value self)
+random_m_rand(mrb_state *mrb, mrb_value self)
 {
   mrb_value max;
-  mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);
+  rand_state *t = random_ptr(self);
 
   max = get_opt(mrb);
-  mrb_random_rand_seed(mrb, t);
-  return mrb_random_mt_rand(mrb, t, max);
+  return random_rand(mrb, t, max);
 }
 
 static mrb_value
-mrb_random_srand(mrb_state *mrb, mrb_value self)
+random_m_srand(mrb_state *mrb, mrb_value self)
 {
-  mrb_value seed;
-  mrb_value old_seed;
-  mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);
-
-  seed = get_opt(mrb);
-  seed = mrb_random_mt_srand(mrb, t, seed);
-  old_seed = t->has_seed? mrb_fixnum_value(t->seed) : mrb_nil_value();
-  if (mrb_nil_p(seed)) {
-    t->has_seed = FALSE;
+  uint32_t seed;
+  uint32_t old_seed;
+  mrb_value sv;
+  rand_state *t = random_ptr(self);
+
+  sv = get_opt(mrb);
+  if (mrb_nil_p(sv)) {
+    seed = (uint32_t)time(NULL) + rand_uint32(t);
   }
   else {
-    mrb_assert(mrb_fixnum_p(seed));
-    t->has_seed = TRUE;
-    t->seed = mrb_fixnum(seed);
+    seed = (uint32_t)mrb_fixnum(sv);
   }
+  old_seed = rand_seed(t, seed);
 
-  return old_seed;
+  return mrb_fixnum_value((mrb_int)old_seed);
 }
 
 /*
@@ -203,25 +214,28 @@ static mrb_value
 mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
 {
   mrb_int i;
-  mt_state *random = NULL;
+  mrb_value max;
+  mrb_value r = mrb_nil_value();
+  rand_state *random;
 
   if (RARRAY_LEN(ary) > 1) {
-    mrb_get_args(mrb, "|d", &random, &mt_state_type);
+    mrb_get_args(mrb, "|o", &r);
 
-    if (random == NULL) {
-      random = get_random_state(mrb);
+    if (mrb_nil_p(r)) {
+      random = random_default_state(mrb);
+    }
+    else {
+      random_check(mrb, r);
+      random = random_ptr(r);
     }
-    mrb_random_rand_seed(mrb, random);
-
     mrb_ary_modify(mrb, mrb_ary_ptr(ary));
-
+    max = mrb_fixnum_value(RARRAY_LEN(ary));
     for (i = RARRAY_LEN(ary) - 1; i > 0; i--)  {
       mrb_int j;
       mrb_value *ptr = RARRAY_PTR(ary);
       mrb_value tmp;
 
-
-      j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary))));
+      j = mrb_fixnum(random_rand(mrb, random, max));
 
       tmp = ptr[i];
       ptr[i] = ptr[j];
@@ -268,15 +282,18 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary)
 {
   mrb_int n = 0;
   mrb_bool given;
-  mt_state *random = NULL;
+  mrb_value r = mrb_nil_value();
+  rand_state *random;
   mrb_int len;
 
-  mrb_get_args(mrb, "|i?d", &n, &given, &random, &mt_state_type);
-  if (random == NULL) {
-    random = get_random_state(mrb);
+  mrb_get_args(mrb, "|i?o", &n, &given, &r);
+  if (mrb_nil_p(r)) {
+    random = random_default_state(mrb);
+  }
+  else {
+    random_check(mrb, r);
+    random = random_ptr(r);
   }
-  mrb_random_rand_seed(mrb, random);
-  mt_rand(random);
   len = RARRAY_LEN(ary);
   if (!given) {                 /* pick one element */
     switch (len) {
@@ -285,7 +302,7 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary)
     case 1:
       return RARRAY_PTR(ary)[0];
     default:
-      return RARRAY_PTR(ary)[mt_rand(random) % len];
+      return RARRAY_PTR(ary)[rand_uint32(random) % len];
     }
   }
   else {
@@ -300,7 +317,7 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary)
 
       for (;;) {
       retry:
-        r = mt_rand(random) % len;
+        r = (mrb_int)(rand_uint32(random) % len);
 
         for (j=0; j<i; j++) {
           if (mrb_fixnum(RARRAY_PTR(result)[j]) == r) {
@@ -318,23 +335,39 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary)
   }
 }
 
+static mrb_value
+random_f_rand(mrb_state *mrb, mrb_value self)
+{
+  rand_state *t = random_default_state(mrb);
+  return random_rand(mrb, t, get_opt(mrb));
+}
+
+static mrb_value
+random_f_srand(mrb_state *mrb, mrb_value self)
+{
+  mrb_value random = random_default(mrb);
+  return random_m_srand(mrb, random);
+}
+
 
 void mrb_mruby_random_gem_init(mrb_state *mrb)
 {
   struct RClass *random;
   struct RClass *array = mrb->array_class;
 
-  mrb_define_method(mrb, mrb->kernel_module, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1));
-  mrb_define_method(mrb, mrb->kernel_module, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1));
+  mrb_assert(sizeof(rand_state) <= ISTRUCT_DATA_SIZE);
+
+  mrb_define_method(mrb, mrb->kernel_module, "rand", random_f_rand, MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, mrb->kernel_module, "srand", random_f_srand, MRB_ARGS_OPT(1));
 
   random = mrb_define_class(mrb, "Random", mrb->object_class);
-  MRB_SET_INSTANCE_TT(random, MRB_TT_DATA);
-  mrb_define_class_method(mrb, random, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1));
-  mrb_define_class_method(mrb, random, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1));
+  MRB_SET_INSTANCE_TT(random, MRB_TT_ISTRUCT);
+  mrb_define_class_method(mrb, random, "rand", random_f_rand, MRB_ARGS_OPT(1));
+  mrb_define_class_method(mrb, random, "srand", random_f_srand, MRB_ARGS_OPT(1));
 
-  mrb_define_method(mrb, random, "initialize", mrb_random_init, MRB_ARGS_OPT(1));
-  mrb_define_method(mrb, random, "rand", mrb_random_rand, MRB_ARGS_OPT(1));
-  mrb_define_method(mrb, random, "srand", mrb_random_srand, MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, random, "initialize", random_m_init, MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, random, "rand", random_m_rand, MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, random, "srand", random_m_srand, MRB_ARGS_OPT(1));
 
   mrb_define_method(mrb, array, "shuffle", mrb_ary_shuffle, MRB_ARGS_OPT(1));
   mrb_define_method(mrb, array, "shuffle!", mrb_ary_shuffle_bang, MRB_ARGS_OPT(1));
diff --git a/third-party/mruby/mrbgems/mruby-random/src/random.h b/third-party/mruby/mrbgems/mruby-random/src/random.h
deleted file mode 100644 (file)
index a4785ae..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
-** random.h - Random module
-**
-** See Copyright Notice in mruby.h
-*/
-
-#ifndef MRUBY_RANDOM_H
-#define MRUBY_RANDOM_H
-
-void mrb_mruby_random_gem_init(mrb_state *mrb);
-
-#endif
index 1653ae4..cf4a551 100644 (file)
@@ -1,48 +1,58 @@
 ##
 # Random Test
 
-assert("Random#srand") do
+assert("Random.new") do
   r1 = Random.new(123)
   r2 = Random.new(123)
-  r1.rand == r2.rand
+  r3 = Random.new(124)
+  assert_equal(r1.rand, r2.rand)
+  assert_not_equal(r1.rand, r3.rand)
 end
 
-assert("Kernel::srand") do
+assert("Kernel.srand") do
   srand(234)
   r1 = rand
   srand(234)
   r2 = rand
-  r1 == r2
+  srand(235)
+  r3 = rand
+  assert_equal(r1, r2)
+  assert_not_equal(r1, r3)
 end
 
-assert("Random::srand") do
+assert("Random.srand") do
   Random.srand(345)
   r1 = rand
   srand(345)
   r2 = Random.rand
-  r1 == r2
+  Random.srand(346)
+  r3 = rand
+  assert_equal(r1, r2)
+  assert_not_equal(r1, r3)
 end
 
-assert("fixnum") do
-  rand(3).class == Fixnum
-end
-
-assert("float") do
-  rand.class == Float
+assert("return class of Kernel.rand") do
+  assert_kind_of(Fixnum, rand(3))
+  assert_kind_of(Fixnum, rand(1.5))
+  assert_kind_of(Float, rand)
+  assert_kind_of(Float, rand(0.5))
 end
 
 assert("Array#shuffle") do
-  ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  orig = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  ary = orig.dup
   shuffled = ary.shuffle
-
-  ary == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and shuffled != ary and 10.times { |x| ary.include? x }
+  assert_equal(orig, ary)
+  assert_not_equal(ary, shuffled)
+  assert_equal(orig, shuffled.sort)
 end
 
 assert('Array#shuffle!') do
-  ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-  ary.shuffle!
-
-  ary != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary.include? x }
+  orig = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  ary = orig.dup
+  assert_same(ary, ary.shuffle!)
+  assert_not_equal(orig, ary)
+  assert_equal(orig, ary.sort)
 end
 
 assert("Array#shuffle(random)") do
@@ -52,12 +62,12 @@ assert("Array#shuffle(random)") do
   end
 
   # verify that the same seed causes the same results
-  ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-  shuffle1 = ary1.shuffle Random.new 345
-  ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-  shuffle2 = ary2.shuffle Random.new 345
-
-  ary1 != shuffle1 and 10.times { |x| shuffle1.include? x } and shuffle1 == shuffle2
+  ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  shuffled1 = ary.shuffle Random.new 345
+  shuffled2 = ary.shuffle Random.new 345
+  shuffled3 = ary.shuffle Random.new 346
+  assert_equal(shuffled1, shuffled2)
+  assert_not_equal(shuffled1, shuffled3)
 end
 
 assert('Array#shuffle!(random)') do
@@ -71,6 +81,42 @@ assert('Array#shuffle!(random)') do
   ary1.shuffle! Random.new 345
   ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   ary2.shuffle! Random.new 345
+  ary3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  ary3.shuffle! Random.new 346
+  assert_equal(ary1, ary2)
+  assert_not_equal(ary1, ary3)
+end
+
+assert('Array#sample') do
+  100.times do
+    assert_include([0, 1, 2], [2, 1, 0].sample)
+    [2, 1, 0].sample(2).each { |sample| assert_include([0, 1, 2], sample) }
+    h = {}
+    (1..10).to_a.sample(7).each do |sample|
+      assert_not_include(h, sample)
+      h[sample] = true
+    end
+  end
+
+  assert_nil([].sample)
+  assert_equal([], [].sample(1))
+  assert_equal([], [2, 1].sample(0))
+  assert_raise(TypeError) { [2, 1].sample(true) }
+  assert_raise(ArgumentError) { [2, 1].sample(-1) }
+end
 
-  ary1 != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary1.include? x } and ary1 == ary2
+assert('Array#sample(random)') do
+  assert_raise(TypeError) do
+    # this will cause an exception due to the wrong argument
+    [1, 2].sample(2, "Not a Random instance")
+  end
+
+  # verify that the same seed causes the same results
+  ary = (1..10).to_a
+  srand(15)
+  samples1 = ary.sample(4)
+  samples2 = ary.sample(4, Random.new(15))
+  samples3 = ary.sample(4, Random.new(16))
+  assert_equal(samples1, samples2)
+  assert_not_equal(samples1, samples3)
 end
index de7925b..a213beb 100644 (file)
@@ -25,4 +25,42 @@ class Range
     end
     ary
   end
+
+  def max(&block)
+    val = self.first
+    last = self.last
+    return super if block
+
+    # fast path for numerics
+    if val.kind_of?(Numeric) && last.kind_of?(Numeric)
+      raise TypeError if exclude_end? && !last.kind_of?(Fixnum)
+      return nil if val > last
+      return nil if val == last && exclude_end?
+
+      max = last
+      max -= 1 if exclude_end?
+      return max
+    end
+
+    # delegate to Enumerable
+    super
+  end
+
+  def min(&block)
+    val = self.first
+    last = self.last
+    return super if block
+
+    # fast path for numerics
+    if val.kind_of?(Numeric) && last.kind_of?(Numeric)
+      return nil if val > last
+      return nil if val == last && exclude_end?
+
+      min = val
+      return min
+    end
+
+    # delegate to Enumerable
+    super
+  end
 end
index 1f66909..2a0b4e9 100644 (file)
@@ -5,24 +5,16 @@
 static mrb_bool
 r_le(mrb_state *mrb, mrb_value a, mrb_value b)
 {
-  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
-  /* output :a < b => -1, a = b =>  0, a > b => +1 */
-
-  if (mrb_fixnum_p(r)) {
-    mrb_int c = mrb_fixnum(r);
-    if (c == 0 || c == -1) return TRUE;
-  }
+  mrb_int n = mrb_cmp(mrb, a, b);
 
+  if (n == 0 || n == -1) return TRUE;
   return FALSE;
 }
 
 static mrb_bool
 r_lt(mrb_state *mrb, mrb_value a, mrb_value b)
 {
-  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
-  /* output :a < b => -1, a = b =>  0, a > b => +1 */
-
-  return mrb_fixnum_p(r) && mrb_fixnum(r) == -1;
+  return mrb_cmp(mrb, a, b) == -1;
 }
 
 /*
@@ -42,12 +34,10 @@ r_lt(mrb_state *mrb, mrb_value a, mrb_value b)
 static mrb_value
 range_cover(mrb_state *mrb, mrb_value range)
 {
-  mrb_value val;
   struct RRange *r = mrb_range_ptr(mrb, range);
+  mrb_value val = mrb_get_arg1(mrb);
   mrb_value beg, end;
 
-  mrb_get_args(mrb, "o", &val);
-
   beg = RANGE_BEG(r);
   end = RANGE_END(r);
 
@@ -106,6 +96,7 @@ range_last(mrb_state *mrb, mrb_value range)
  *    ('a'..'z').size  #=> nil
  */
 
+#ifndef MRB_WITHOUT_FLOAT
 static mrb_value
 range_size(mrb_state *mrb, mrb_value range)
 {
@@ -158,6 +149,28 @@ range_size(mrb_state *mrb, mrb_value range)
   }
   return mrb_nil_value();
 }
+#else
+static mrb_value
+range_size(mrb_state *mrb, mrb_value range)
+{
+  struct RRange *r = mrb_range_ptr(mrb, range);
+  mrb_value beg, end;
+  mrb_int excl;
+
+  beg = RANGE_BEG(r);
+  end = RANGE_END(r);
+  excl = RANGE_EXCL(r) ? 0 : 1;
+
+  if (mrb_fixnum_p(beg) && mrb_fixnum_p(end)) {
+    mrb_int a = mrb_fixnum(beg);
+    mrb_int b = mrb_fixnum(end);
+    mrb_int c = b - a + excl;
+
+    return mrb_fixnum_value(c);
+  }
+  return mrb_nil_value();
+}
+#endif /* MRB_WITHOUT_FLOAT */
 
 void
 mrb_mruby_range_ext_gem_init(mrb_state* mrb)
index efcbdab..865e46d 100644 (file)
@@ -10,6 +10,8 @@ end
 assert('Range#first') do
   assert_equal 10, (10..20).first
   assert_equal [10, 11, 12], (10..20).first(3)
+
+  skip unless Object.const_defined?(:Float)
   assert_equal [0, 1, 2], (0..Float::INFINITY).first(3)
 end
 
@@ -23,10 +25,118 @@ end
 assert('Range#size') do
   assert_equal 42, (1..42).size
   assert_equal 41, (1...42).size
+  assert_nil ('a'..'z').size
+
+  skip unless Object.const_defined?(:Float)
   assert_equal 6, (1...6.3).size
   assert_equal 5, (1...6.0).size
   assert_equal 5, (1.1...6).size
   assert_equal 15, (1.0..15.9).size
   assert_equal Float::INFINITY, (0..Float::INFINITY).size
-  assert_nil ('a'..'z').size
+end
+
+assert('Range#max') do
+  # returns the maximum value in the range when called with no arguments
+  assert_equal 10, (1..10).max
+  assert_equal 9, (1...10).max
+  assert_equal 536870911, (0...2**29).max
+
+  # returns nil when the endpoint is less than the start point
+  assert_equal nil, (100..10).max
+
+  # returns nil when the endpoint equals the start point and the range is exclusive
+  assert_equal nil, (5...5).max
+
+  # returns the endpoint when the endpoint equals the start point and the range is inclusive
+  assert_equal 5, (5..5).max
+
+  skip unless Object.const_defined?(:Float)
+
+  # returns the maximum value in the Float range when called with no arguments
+  assert_equal 908.1111, (303.20..908.1111).max
+
+  # raises TypeError when called on an exclusive range and a non Integer value
+  assert_raise(TypeError) { (303.20...908.1111).max }
+
+  # returns nil when the endpoint is less than the start point in a Float range
+  assert_equal nil, (3003.20..908.1111).max
+end
+
+assert('Range#max given a block') do
+  # passes each pair of values in the range to the block
+  acc = []
+  (1..10).max do |a, b|
+    acc << a
+    acc << b
+    a
+  end
+  (1..10).each do |value|
+    assert_true acc.include?(value)
+  end
+
+  # passes each pair of elements to the block in reversed order
+  acc = []
+  (1..5).max do |a, b|
+    acc << [a, b]
+    a
+  end
+  assert_equal [[2, 1], [3, 2], [4, 3], [5, 4]], acc
+
+  # returns the element the block determines to be the maximum
+  assert_equal 1, ((1..3).max { |_a, _b| -3 })
+
+  # returns nil when the endpoint is less than the start point
+  assert_equal nil, ((100..10).max { |x, y| x <=> y })
+  assert_equal nil, ((5...5).max { |x, y| x <=> y })
+end
+
+assert('Range#min') do
+  # returns the minimum value in the range when called with no arguments
+  assert_equal 1, (1..10).min
+  assert_equal 1, (1...10).min
+
+  # returns nil when the start point is greater than the endpoint
+  assert_equal nil, (100..10).min
+
+  # returns nil when the endpoint equals the start point and the range is exclusive
+  assert_equal nil, (5...5).max
+
+  # returns the endpoint when the endpoint equals the start point and the range is inclusive
+  assert_equal 5, (5..5).max
+
+  skip unless Object.const_defined?(:Float)
+
+  # returns the minimum value in the Float range when called with no arguments
+  assert_equal 303.20, (303.20..908.1111).min
+
+  # returns nil when the start point is greater than the endpoint in a Float range
+  assert_equal nil, (3003.20..908.1111).max
+end
+
+assert('Range#min given a block') do
+  # passes each pair of values in the range to the block
+  acc = []
+  (1..10).min do |a, b|
+    acc << a
+    acc << b
+    a
+  end
+  (1..10).each do |value|
+    assert_true acc.include?(value)
+  end
+
+  # passes each pair of elements to the block in reversed order
+  acc = []
+  (1..5).min do |a, b|
+    acc << [a, b]
+    a
+  end
+  assert_equal [[2, 1], [3, 1], [4, 1], [5, 1]], acc
+
+  # returns the element the block determines to be the minimum
+  assert_equal 3, ((1..3).min { |_a, _b| -3 })
+
+  # returns nil when the start point is greater than the endpoint
+  assert_equal nil, ((100..10).min { |x, y| x <=> y })
+  assert_equal nil, ((5...5).min { |x, y| x <=> y })
 end
diff --git a/third-party/mruby/mrbgems/mruby-rational/mrbgem.rake b/third-party/mruby/mrbgems/mruby-rational/mrbgem.rake
new file mode 100644 (file)
index 0000000..4b540de
--- /dev/null
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-rational') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Rational class'
+end
diff --git a/third-party/mruby/mrbgems/mruby-rational/mrblib/rational.rb b/third-party/mruby/mrbgems/mruby-rational/mrblib/rational.rb
new file mode 100644 (file)
index 0000000..b65f77e
--- /dev/null
@@ -0,0 +1,115 @@
+class Rational < Numeric
+  def inspect
+    "(#{to_s})"
+  end
+
+  def to_s
+    "#{numerator}/#{denominator}"
+  end
+
+  def *(rhs)
+    if rhs.is_a? Rational
+      Rational(numerator * rhs.numerator, denominator * rhs.denominator)
+    elsif rhs.is_a? Integer
+      Rational(numerator * rhs, denominator)
+    elsif rhs.is_a? Numeric
+      numerator * rhs / denominator
+    end
+  end
+
+  def +(rhs)
+    if rhs.is_a? Rational
+      Rational(numerator * rhs.denominator + rhs.numerator * denominator, denominator * rhs.denominator)
+    elsif rhs.is_a? Integer
+      Rational(numerator + rhs * denominator, denominator)
+    elsif rhs.is_a? Numeric
+      (numerator + rhs * denominator) / denominator
+    end
+  end
+
+  def -(rhs)
+    if rhs.is_a? Rational
+      Rational(numerator * rhs.denominator - rhs.numerator * denominator, denominator * rhs.denominator)
+    elsif rhs.is_a? Integer
+      Rational(numerator - rhs * denominator, denominator)
+    elsif rhs.is_a? Numeric
+      (numerator - rhs * denominator) / denominator
+    end
+  end
+
+  def /(rhs)
+    if rhs.is_a? Rational
+      Rational(numerator * rhs.denominator, denominator * rhs.numerator)
+    elsif rhs.is_a? Integer
+      Rational(numerator, denominator * rhs)
+    elsif rhs.is_a? Numeric
+      numerator / rhs / denominator
+    end
+  end
+
+  def <=>(rhs)
+    if rhs.is_a?(Integral)
+      return numerator <=> rhs if denominator == 1
+      rhs = Rational(rhs)
+    end
+
+    case rhs
+    when Rational
+      (numerator * rhs.denominator - denominator * rhs.numerator) <=> 0
+    when Numeric
+      (rhs <=> self)&.-@
+    else
+      nil
+    end
+  end
+
+  def ==(rhs)
+    return true if self.equal?(rhs)
+    if rhs.is_a?(Integral) && denominator == 1
+      return numerator == rhs
+    end
+    if rhs.is_a?(Rational)
+      numerator * rhs.denominator == denominator * rhs.numerator
+    else
+      rhs == self
+    end
+  end
+end
+
+class Numeric
+  def to_r
+    Rational(self, 1)
+  end
+end
+
+module Kernel
+  def Rational(numerator, denominator = 1)
+    a = numerator
+    b = denominator
+    a, b = b, a % b until b == 0
+    Rational._new(numerator.div(a), denominator.div(a))
+  end
+
+  [:+, :-, :*, :/, :<=>, :==, :<, :<=, :>, :>=].each do |op|
+    original_operator_name = :"__original_operator_#{op}_rational"
+    Fixnum.instance_eval do
+      alias_method original_operator_name, op
+      define_method op do |rhs|
+        if rhs.is_a? Rational
+          Rational(self).__send__(op, rhs)
+        else
+          __send__(original_operator_name, rhs)
+        end
+      end
+    end
+    Float.instance_eval do
+      alias_method original_operator_name, op
+      define_method op do |rhs|
+        if rhs.is_a? Rational
+          rhs = rhs.to_f
+        end
+        __send__(original_operator_name, rhs)
+      end
+    end if Object.const_defined?(:Float)
+  end
+end
diff --git a/third-party/mruby/mrbgems/mruby-rational/src/rational.c b/third-party/mruby/mrbgems/mruby-rational/src/rational.c
new file mode 100644 (file)
index 0000000..676a1dc
--- /dev/null
@@ -0,0 +1,209 @@
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/string.h>
+#include <mruby/numeric.h>
+
+struct mrb_rational {
+  mrb_int numerator;
+  mrb_int denominator;
+};
+
+#if MRB_INT_MAX <= INTPTR_MAX
+
+#define RATIONAL_USE_ISTRUCT
+/* use TT_ISTRUCT */
+#include <mruby/istruct.h>
+
+#define rational_ptr(mrb, v) (struct mrb_rational*)mrb_istruct_ptr(v)
+
+static struct RBasic*
+rational_alloc(mrb_state *mrb, struct RClass *c, struct mrb_rational **p)
+{
+  struct RIStruct *s;
+
+  s = (struct RIStruct*)mrb_obj_alloc(mrb, MRB_TT_ISTRUCT, c);
+  *p = (struct mrb_rational*)s->inline_data;
+
+  return (struct RBasic*)s;
+}
+
+#else
+/* use TT_DATA */
+#include <mruby/data.h>
+
+static const struct mrb_data_type mrb_rational_type = {"Rational", mrb_free};
+
+static struct RBasic*
+rational_alloc(mrb_state *mrb, struct RClass *c, struct mrb_rational **p)
+{
+  struct RData *d;
+
+  Data_Make_Struct(mrb, c, struct mrb_rational, &mrb_rational_type, *p, d);
+
+  return (struct RBasic*)d;
+}
+
+static struct mrb_rational*
+rational_ptr(mrb_state *mrb, mrb_value v)
+{
+  struct mrb_rational *p;
+
+  p = DATA_GET_PTR(mrb, v, &mrb_rational_type, struct mrb_rational);
+  if (!p) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized rational");
+  }
+  return p;
+}
+#endif
+
+static mrb_value
+rational_numerator(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_rational *p = rational_ptr(mrb, self);
+  return mrb_fixnum_value(p->numerator);
+}
+
+static mrb_value
+rational_denominator(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_rational *p = rational_ptr(mrb, self);
+  return mrb_fixnum_value(p->denominator);
+}
+
+static mrb_value
+rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator)
+{
+  struct RClass *c = mrb_class_get(mrb, "Rational");
+  struct mrb_rational *p;
+  struct RBasic *rat = rational_alloc(mrb, c, &p);
+  p->numerator = numerator;
+  p->denominator = denominator;
+  MRB_SET_FROZEN_FLAG(rat);
+  return mrb_obj_value(rat);
+}
+
+static mrb_value
+rational_s_new(mrb_state *mrb, mrb_value self)
+{
+  mrb_int numerator, denominator;
+
+#ifdef MRB_WITHOUT_FLOAT
+  mrb_get_args(mrb, "ii", &numerator, &denominator);
+#else
+
+#define DROP_PRECISION(f, num, denom) \
+  do { \
+      while (f < (mrb_float)MRB_INT_MIN || f > (mrb_float)MRB_INT_MAX) { \
+        num /= 2; \
+        denom /= 2; \
+      } \
+  } while (0)
+
+  mrb_value numv, denomv;
+
+  mrb_get_args(mrb, "oo", &numv, &denomv);
+  if (mrb_fixnum_p(numv)) {
+    numerator = mrb_fixnum(numv);
+
+    if (mrb_fixnum_p(denomv)) {
+      denominator = mrb_fixnum(denomv);
+    }
+    else {
+      mrb_float denomf = mrb_to_flo(mrb, denomv);
+
+      DROP_PRECISION(denomf, numerator, denomf);
+      denominator = (mrb_int)denomf;
+    }
+  }
+  else {
+    mrb_float numf = mrb_to_flo(mrb, numv);
+
+    if (mrb_fixnum_p(denomv)) {
+      denominator = mrb_fixnum(denomv);
+    }
+    else {
+      mrb_float denomf = mrb_to_flo(mrb, denomv);
+
+      DROP_PRECISION(denomf, numf, denomf);
+      denominator = (mrb_int)denomf;
+    }
+
+    DROP_PRECISION(numf, numf, denominator);
+    numerator = (mrb_int)numf;
+  }
+#endif
+
+  return rational_new(mrb, numerator, denominator);
+}
+
+#ifndef MRB_WITHOUT_FLOAT
+static mrb_value
+rational_to_f(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_rational *p = rational_ptr(mrb, self);
+  mrb_float f = (mrb_float)p->numerator / (mrb_float)p->denominator;
+
+  return mrb_float_value(mrb, f);
+}
+#endif
+
+static mrb_value
+rational_to_i(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_rational *p = rational_ptr(mrb, self);
+  if (p->denominator == 0) {
+    mrb_raise(mrb, mrb->eStandardError_class, "divided by 0");
+  }
+  return mrb_fixnum_value(p->numerator / p->denominator);
+}
+
+static mrb_value
+rational_to_r(mrb_state *mrb, mrb_value self)
+{
+  return self;
+}
+
+static mrb_value
+rational_negative_p(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_rational *p = rational_ptr(mrb, self);
+  if (p->numerator < 0) {
+    return mrb_true_value();
+  }
+  return mrb_false_value();
+}
+
+static mrb_value
+fix_to_r(mrb_state *mrb, mrb_value self)
+{
+  return rational_new(mrb, mrb_fixnum(self), 1);
+}
+
+void mrb_mruby_rational_gem_init(mrb_state *mrb)
+{
+  struct RClass *rat;
+
+  rat = mrb_define_class(mrb, "Rational", mrb_class_get(mrb, "Numeric"));
+#ifdef RATIONAL_USE_ISTRUCT
+  MRB_SET_INSTANCE_TT(rat, MRB_TT_ISTRUCT);
+  mrb_assert(sizeof(struct mrb_rational) < ISTRUCT_DATA_SIZE);
+#else
+  MRB_SET_INSTANCE_TT(rat, MRB_TT_DATA);
+#endif
+  mrb_undef_class_method(mrb, rat, "new");
+  mrb_define_class_method(mrb, rat, "_new", rational_s_new, MRB_ARGS_REQ(2));
+  mrb_define_method(mrb, rat, "numerator", rational_numerator, MRB_ARGS_NONE());
+  mrb_define_method(mrb, rat, "denominator", rational_denominator, MRB_ARGS_NONE());
+#ifndef MRB_WITHOUT_FLOAT
+  mrb_define_method(mrb, rat, "to_f", rational_to_f, MRB_ARGS_NONE());
+#endif
+  mrb_define_method(mrb, rat, "to_i", rational_to_i, MRB_ARGS_NONE());
+  mrb_define_method(mrb, rat, "to_r", rational_to_r, MRB_ARGS_NONE());
+  mrb_define_method(mrb, rat, "negative?", rational_negative_p, MRB_ARGS_NONE());
+  mrb_define_method(mrb, mrb->fixnum_class, "to_r", fix_to_r, MRB_ARGS_NONE());
+}
+
+void
+mrb_mruby_rational_gem_final(mrb_state* mrb)
+{
+}
diff --git a/third-party/mruby/mrbgems/mruby-rational/test/rational.rb b/third-party/mruby/mrbgems/mruby-rational/test/rational.rb
new file mode 100644 (file)
index 0000000..a8ebb8e
--- /dev/null
@@ -0,0 +1,308 @@
+class UserDefinedNumeric < Numeric
+  def initialize(n)
+    @n = n
+  end
+
+  def <=>(rhs)
+    return nil unless rhs.respond_to?(:to_i)
+    rhs = rhs.to_i
+    rhs < 0 ? nil : @n <=> rhs
+  end
+
+  def inspect
+    "#{self.class}(#{@n})"
+  end
+end
+
+class ComplexLikeNumeric < UserDefinedNumeric
+  def ==(rhs)
+    @n == 0 && rhs == 0
+  end
+
+  undef <=>
+end
+
+def assert_rational(exp, real)
+  assert "assert_rational" do
+    assert_float exp.numerator,   real.numerator
+    assert_float exp.denominator, real.denominator
+  end
+end
+
+def assert_equal_rational(exp, o1, o2)
+  assert "assert_equal_rational" do
+    if exp
+      assert_operator(o1, :==, o2)
+      assert_not_operator(o1, :!=, o2)
+    else
+      assert_not_operator(o1, :==, o2)
+      assert_operator(o1, :!=, o2)
+    end
+  end
+end
+
+def assert_cmp(exp, o1, o2)
+  if exp == (o1 <=> o2)
+    pass
+  else
+    flunk "", "    Expected #{o1.inspect} <=> #{o2.inspect} to be #{exp}."
+  end
+end
+
+assert 'Rational' do
+  r = 5r
+  assert_equal(Rational, r.class)
+  assert_equal([5, 1], [r.numerator, r.denominator])
+end
+
+assert 'Kernel#Rational' do
+  r = Rational(4,10)
+  assert_equal(2, r.numerator)
+  assert_equal(5, r.denominator)
+
+  r = Rational(3)
+  assert_equal(3, r.numerator)
+  assert_equal(1, r.denominator)
+
+  assert_raise(ArgumentError) { Rational() }
+  assert_raise(ArgumentError) { Rational(1,2,3) }
+end
+
+assert 'Rational#to_f' do
+  assert_float(2.0, Rational(2).to_f)
+  assert_float(2.25, Rational(9, 4).to_f)
+  assert_float(-0.75, Rational(-3, 4).to_f)
+  assert_float(6.666666666666667, Rational(20, 3).to_f)
+end
+
+assert 'Rational#to_i' do
+  assert_equal(0, Rational(2, 3).to_i)
+  assert_equal(3, Rational(3).to_i)
+  assert_equal(300, Rational(300.6).to_i)
+  assert_equal(1, Rational(98, 71).to_i)
+  assert_equal(-15, Rational(-30, 2).to_i)
+end
+
+assert 'Rational#*' do
+  assert_rational(Rational(4, 9),    Rational(2, 3)  * Rational(2, 3))
+  assert_rational(Rational(900, 1),  Rational(900)   * Rational(1))
+  assert_rational(Rational(1, 1),    Rational(-2, 9) * Rational(-9, 2))
+  assert_rational(Rational(9, 2),    Rational(9, 8)  * 4)
+  assert_float(   21.77777777777778, Rational(20, 9) * 9.8)
+end
+
+assert 'Rational#+' do
+  assert_rational(Rational(4, 3),     Rational(2, 3)  + Rational(2, 3))
+  assert_rational(Rational(901, 1),   Rational(900)   + Rational(1))
+  assert_rational(Rational(-85, 18),  Rational(-2, 9) + Rational(-9, 2))
+  assert_rational(Rational(41, 8),    Rational(9, 8)  + 4)
+  assert_float(   12.022222222222222, Rational(20, 9) + 9.8)
+end
+
+assert 'Rational#-' do
+  assert_rational(Rational(0, 1),     Rational(2, 3)  - Rational(2, 3))
+  assert_rational(Rational(899, 1),   Rational(900)   - Rational(1))
+  assert_rational(Rational(77, 18),   Rational(-2, 9) - Rational(-9, 2))
+  assert_rational(Rational(-23, 8),   Rational(9, 8)  - 4)
+  assert_float(   -7.577777777777778, Rational(20, 9) - 9.8)
+end
+
+assert 'Rational#/' do
+  assert_rational(Rational(1, 1),      Rational(2, 3)  / Rational(2, 3))
+  assert_rational(Rational(900, 1),    Rational(900)   / Rational(1))
+  assert_rational(Rational(4, 81),     Rational(-2, 9) / Rational(-9, 2))
+  assert_rational(Rational(9, 32),     Rational(9, 8)  / 4)
+  assert_float(   0.22675736961451246, Rational(20, 9) / 9.8)
+end
+
+assert 'Rational#==, Rational#!=' do
+  assert_equal_rational(true, Rational(1,1), Rational(1))
+  assert_equal_rational(true, Rational(-1,1), -1r)
+  assert_equal_rational(true, Rational(13,4), 3.25)
+  assert_equal_rational(true, Rational(13,3.25), Rational(4,1))
+  assert_equal_rational(true, Rational(-3,-4), Rational(3,4))
+  assert_equal_rational(true, Rational(-4,5), Rational(4,-5))
+  assert_equal_rational(true, Rational(4,2), 2)
+  assert_equal_rational(true, Rational(-4,2), -2)
+  assert_equal_rational(true, Rational(4,-2), -2)
+  assert_equal_rational(true, Rational(4,2), 2.0)
+  assert_equal_rational(true, Rational(-4,2), -2.0)
+  assert_equal_rational(true, Rational(4,-2), -2.0)
+  assert_equal_rational(true, Rational(8,6), Rational(4,3))
+  assert_equal_rational(false, Rational(13,4), 3)
+  assert_equal_rational(false, Rational(13,4), 3.3)
+  assert_equal_rational(false, Rational(2,1), 1r)
+  assert_equal_rational(false, Rational(1), nil)
+  assert_equal_rational(false, Rational(1), '')
+  assert_equal_rational(true, 0r, UserDefinedNumeric.new(0))
+  assert_equal_rational(true, 1r, UserDefinedNumeric.new(1))
+  assert_equal_rational(false, 1r, UserDefinedNumeric.new(2))
+  assert_equal_rational(false, -1r, UserDefinedNumeric.new(-1))
+  assert_equal_rational(true, 0r, ComplexLikeNumeric.new(0))
+  assert_equal_rational(false, 1r, ComplexLikeNumeric.new(1))
+  assert_equal_rational(false, 1r, ComplexLikeNumeric.new(2))
+end
+
+assert 'Fixnum#==(Rational), Fixnum#!=(Rational)' do
+  assert_equal_rational(true, 2, Rational(4,2))
+  assert_equal_rational(true, -2, Rational(-4,2))
+  assert_equal_rational(true, -2, Rational(4,-2))
+  assert_equal_rational(false, 3, Rational(13,4))
+end
+
+assert 'Float#==(Rational), Float#!=(Rational)' do
+  assert_equal_rational(true, 2.0, Rational(4,2))
+  assert_equal_rational(true, -2.0, Rational(-4,2))
+  assert_equal_rational(true, -2.0, Rational(4,-2))
+  assert_equal_rational(false, 3.3, Rational(13,4))
+end
+
+assert 'Rational#<=>' do
+  assert_cmp(-1, Rational(-1), Rational(0))
+  assert_cmp(0, Rational(0), Rational(0))
+  assert_cmp(1, Rational(1), Rational(0))
+  assert_cmp(-1, Rational(-1), 0)
+  assert_cmp(0, Rational(0), 0)
+  assert_cmp(1, Rational(1), 0)
+  assert_cmp(-1, Rational(-1), 0.0)
+  assert_cmp(0, Rational(0), 0.0)
+  assert_cmp(1, Rational(1), 0.0)
+  assert_cmp(-1, Rational(1,2), Rational(2,3))
+  assert_cmp(0, Rational(2,3), Rational(2,3))
+  assert_cmp(1, Rational(2,3), Rational(1,2))
+  assert_cmp(1, Rational(2,3), Rational(1,2))
+  assert_cmp(1, Rational(0), Rational(-1))
+  assert_cmp(-1, Rational(0), Rational(1))
+  assert_cmp(1, Rational(2,3), Rational(1,2))
+  assert_cmp(0, Rational(2,3), Rational(2,3))
+  assert_cmp(-1, Rational(1,2), Rational(2,3))
+  assert_cmp(-1, Rational(1,2), Rational(2,3))
+  assert_cmp(nil, 3r, "3")
+  assert_cmp(1, 3r, UserDefinedNumeric.new(2))
+  assert_cmp(0, 3r, UserDefinedNumeric.new(3))
+  assert_cmp(-1, 3r, UserDefinedNumeric.new(4))
+  assert_cmp(nil, Rational(-3), UserDefinedNumeric.new(5))
+  assert_raise(NoMethodError) { 0r <=> ComplexLikeNumeric.new(0) }
+  assert_raise(NoMethodError) { 1r <=> ComplexLikeNumeric.new(2) }
+end
+
+assert 'Fixnum#<=>(Rational)' do
+  assert_cmp(-1, -2, Rational(-9,5))
+  assert_cmp(0, 5, 5r)
+  assert_cmp(1, 3, Rational(8,3))
+end
+
+assert 'Float#<=>(Rational)' do
+  assert_cmp(-1, -2.1, Rational(-9,5))
+  assert_cmp(0, 5.0, 5r)
+  assert_cmp(1, 2.7, Rational(8,3))
+end
+
+assert 'Rational#<' do
+  assert_operator(Rational(1,2), :<, Rational(2,3))
+  assert_not_operator(Rational(2,3), :<, Rational(2,3))
+  assert_operator(Rational(2,3), :<, 1)
+  assert_not_operator(2r, :<, 2)
+  assert_not_operator(Rational(2,3), :<, -3)
+  assert_operator(Rational(-4,3), :<, -0.3)
+  assert_not_operator(Rational(13,4), :<, 3.25)
+  assert_not_operator(Rational(2,3), :<, 0.6)
+  assert_raise(ArgumentError) { 1r < "2" }
+end
+
+assert 'Fixnum#<(Rational)' do
+  assert_not_operator(1, :<, Rational(2,3))
+  assert_not_operator(2, :<, 2r)
+  assert_operator(-3, :<, Rational(2,3))
+end
+
+assert 'Float#<(Rational)' do
+  assert_not_operator(-0.3, :<, Rational(-4,3))
+  assert_not_operator(3.25, :<, Rational(13,4))
+  assert_operator(0.6, :<, Rational(2,3))
+end
+
+assert 'Rational#<=' do
+  assert_operator(Rational(1,2), :<=, Rational(2,3))
+  assert_operator(Rational(2,3), :<=, Rational(2,3))
+  assert_operator(Rational(2,3), :<=, 1)
+  assert_operator(2r, :<=, 2)
+  assert_not_operator(Rational(2,3), :<=, -3)
+  assert_operator(Rational(-4,3), :<=, -0.3)
+  assert_operator(Rational(13,4), :<=, 3.25)
+  assert_not_operator(Rational(2,3), :<=, 0.6)
+  assert_raise(ArgumentError) { 1r <= "2" }
+end
+
+assert 'Fixnum#<=(Rational)' do
+  assert_not_operator(1, :<=, Rational(2,3))
+  assert_operator(2, :<=, 2r)
+  assert_operator(-3, :<=, Rational(2,3))
+end
+
+assert 'Float#<=(Rational)' do
+  assert_not_operator(-0.3, :<=, Rational(-4,3))
+  assert_operator(3.25, :<=, Rational(13,4))
+  assert_operator(0.6, :<=, Rational(2,3))
+end
+
+assert 'Rational#>' do
+  assert_not_operator(Rational(1,2), :>, Rational(2,3))
+  assert_not_operator(Rational(2,3), :>, Rational(2,3))
+  assert_not_operator(Rational(2,3), :>, 1)
+  assert_not_operator(2r, :>, 2)
+  assert_operator(Rational(2,3), :>, -3)
+  assert_not_operator(Rational(-4,3), :>, -0.3)
+  assert_not_operator(Rational(13,4), :>, 3.25)
+  assert_operator(Rational(2,3), :>, 0.6)
+  assert_raise(ArgumentError) { 1r > "2" }
+end
+
+assert 'Fixnum#>(Rational)' do
+  assert_operator(1, :>, Rational(2,3))
+  assert_not_operator(2, :>, 2r)
+  assert_not_operator(-3, :>, Rational(2,3))
+end
+
+assert 'Float#>(Rational)' do
+  assert_operator(-0.3, :>, Rational(-4,3))
+  assert_not_operator(3.25, :>, Rational(13,4))
+  assert_not_operator(0.6, :>, Rational(2,3))
+end
+
+assert 'Rational#>=' do
+  assert_not_operator(Rational(1,2), :>=, Rational(2,3))
+  assert_operator(Rational(2,3), :>=, Rational(2,3))
+  assert_not_operator(Rational(2,3), :>=, 1)
+  assert_operator(2r, :>=, 2)
+  assert_operator(Rational(2,3), :>=, -3)
+  assert_not_operator(Rational(-4,3), :>=, -0.3)
+  assert_operator(Rational(13,4), :>=, 3.25)
+  assert_operator(Rational(2,3), :>=, 0.6)
+  assert_raise(ArgumentError) { 1r >= "2" }
+end
+
+assert 'Fixnum#>=(Rational)' do
+  assert_operator(1, :>=, Rational(2,3))
+  assert_operator(2, :>=, 2r)
+  assert_not_operator(-3, :>=, Rational(2,3))
+end
+
+assert 'Float#>=(Rational)' do
+  assert_operator(-0.3, :>=, Rational(-4,3))
+  assert_operator(3.25, :>=, Rational(13,4))
+  assert_not_operator(0.6, :>=, Rational(2,3))
+end
+
+assert 'Rational#negative?' do
+  assert_predicate(Rational(-2,3), :negative?)
+  assert_predicate(Rational(2,-3), :negative?)
+  assert_not_predicate(Rational(2,3), :negative?)
+  assert_not_predicate(Rational(0), :negative?)
+end
+
+assert 'Rational#frozen?' do
+  assert_predicate(1r, :frozen?)
+  assert_predicate(Rational(2,3), :frozen?)
+  assert_predicate(4/5r, :frozen?)
+end
diff --git a/third-party/mruby/mrbgems/mruby-sleep/.gitignore b/third-party/mruby/mrbgems/mruby-sleep/.gitignore
deleted file mode 100644 (file)
index b9f9e71..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/mruby
-
-*.so
-*.a
\ No newline at end of file
diff --git a/third-party/mruby/mrbgems/mruby-sleep/.travis.yml b/third-party/mruby/mrbgems/mruby-sleep/.travis.yml
deleted file mode 100644 (file)
index ad6b007..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-dist: trusty
-
-language: c
-compiler:
-  - gcc
-  - clang
-env:
-  - MRUBY_VERSION=1.2.0
-  - MRUBY_VERSION=master
-matrix:
-  allow_failures:
-    - env: MRUBY_VERSION=master
-branches:
-  only:
-    - master
-addons:
-  apt:
-    packages:
-      - rake
-      - bison
-      - git
-      - gperf
-      # - aclocal
-      # - automake
-      # - autoconf
-      # - autotools-dev
-
-script:
-  - rake test
\ No newline at end of file
diff --git a/third-party/mruby/mrbgems/mruby-sleep/.travis_build_config.rb b/third-party/mruby/mrbgems/mruby-sleep/.travis_build_config.rb
deleted file mode 100644 (file)
index b32e38a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-MRuby::Build.new do |conf|
-  toolchain :gcc
-  conf.gembox 'default'
-  conf.gem '../mruby-sleep'
-  conf.enable_test
-end
diff --git a/third-party/mruby/mrbgems/mruby-sleep/Rakefile b/third-party/mruby/mrbgems/mruby-sleep/Rakefile
deleted file mode 100644 (file)
index 5e3c461..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-MRUBY_CONFIG=File.expand_path(ENV["MRUBY_CONFIG"] || ".travis_build_config.rb")
-MRUBY_VERSION=ENV["MRUBY_VERSION"] || "1.2.0"
-
-file :mruby do
-  cmd =  "git clone --depth=1 git://github.com/mruby/mruby.git"
-  if MRUBY_VERSION != 'master'
-    cmd << " && cd mruby"
-    cmd << " && git fetch --tags && git checkout $(git rev-parse #{MRUBY_VERSION})"
-  end
-  sh cmd
-end
-
-desc "compile binary"
-task :compile => :mruby do
-  sh "cd mruby && MRUBY_CONFIG=#{MRUBY_CONFIG} rake all"
-end
-
-desc "test"
-task :test => :mruby do
-  sh "cd mruby && MRUBY_CONFIG=#{MRUBY_CONFIG} rake all test"
-end
-
-desc "cleanup"
-task :clean do
-  exit 0 unless File.directory?('mruby')
-  sh "cd mruby && rake deep_clean"
-end
-
-task :default => :compile
index 8827b35..7a303b8 100644 (file)
@@ -1,5 +1,5 @@
 MRuby::Gem::Specification.new('mruby-sleep') do |spec|
   spec.license = 'MIT'
-  spec.authors = 'MATSUMOTO Ryosuke'
+  spec.authors = ['MATSUMOTO Ryosuke', 'mruby developers']
   spec.version = '0.0.1'
 end
index 3f8ef90..1a0fba0 100644 (file)
@@ -2,6 +2,7 @@
 ** mrb_sleep - sleep methods for mruby
 **
 ** Copyright (c) mod_mruby developers 2012-
+** Copyright (c) mruby developers 2018
 **
 ** Permission is hereby granted, free of charge, to any person obtaining
 ** a copy of this software and associated documentation files (the
@@ -29,7 +30,7 @@
 #ifdef _WIN32
     #include <windows.h>
     #define sleep(x) Sleep(x * 1000)
-    #define usleep(x) Sleep((DWORD)((x)<1000) ? 1 : ((x)/1000))
+    #define usleep(x) Sleep((DWORD)(((x)<1000) ? 1 : ((x)/1000)))
 #else
     #include <unistd.h>
     #include <sys/time.h>
diff --git a/third-party/mruby/mrbgems/mruby-socket/.travis.yml b/third-party/mruby/mrbgems/mruby-socket/.travis.yml
deleted file mode 100644 (file)
index 6476289..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-language: c
-sudo: false
-script:
-  - "ruby run_test.rb all test"
index 7428cfa..947a24e 100644 (file)
@@ -20,7 +20,7 @@ Date: Tue, 21 May 2013 04:31:30 GMT
 ```
 
 ## Requirement
-- [iij/mruby-io](https://github.com/iij/mruby-io) mrbgem
+- [mruby-io](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-io) mrbgem
 - [iij/mruby-mtest](https://github.com/iij/mruby-mtest) mrgbem to run tests
 - system must have RFC3493 basic socket interface
 - and some POSIX API...
@@ -35,6 +35,7 @@ Date: Tue, 21 May 2013 04:31:30 GMT
 ## License
 
 Copyright (c) 2013 Internet Initiative Japan Inc.
+Copyright (c) 2017 mruby developers
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
index b0894e0..6271c45 100644 (file)
@@ -1,13 +1,13 @@
 MRuby::Gem::Specification.new('mruby-socket') do |spec|
   spec.license = 'MIT'
-  spec.authors = 'Internet Initiative Japan'
+  spec.authors = ['Internet Initiative Japan', 'mruby developers']
   spec.summary = 'standard socket class'
 
   spec.cc.include_paths << "#{build.root}/src"
   #spec.cc.defines << "HAVE_SA_LEN=0"
 
   # If Windows, use winsock
-  if ( /mswin|mingw|win32/ =~ RUBY_PLATFORM ) then
+  if for_windows?
     spec.linker.libraries << "wsock32"
     spec.linker.libraries << "ws2_32"
   end
diff --git a/third-party/mruby/mrbgems/mruby-socket/run_test.rb b/third-party/mruby/mrbgems/mruby-socket/run_test.rb
deleted file mode 100644 (file)
index 87a222f..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env ruby
-#
-# mrbgems test runner
-#
-
-if __FILE__ == $0
-  repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
-  build_args = ARGV
-
-  Dir.mkdir 'tmp'  unless File.exist?('tmp')
-  unless File.exist?(dir)
-    system "git clone #{repository} #{dir}"
-  end
-
-  exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
-end
-
-MRuby::Build.new do |conf|
-  toolchain :gcc
-  conf.gembox 'default'
-
-  conf.gem :git => 'https://github.com/iij/mruby-mtest.git'
-  conf.gem :git => 'https://github.com/iij/mruby-io.git'
-  conf.gem :git => 'https://github.com/iij/mruby-pack.git'
-
-  conf.gem File.expand_path(File.dirname(__FILE__))
-  conf.enable_test
-end
index dff1767..8a0d9df 100644 (file)
 #include "mruby/array.h"
 #include "mruby/class.h"
 #include "mruby/data.h"
+#include "mruby/numeric.h"
 #include "mruby/string.h"
 #include "mruby/variable.h"
-#include "error.h"
+#include "mruby/error.h"
 
 #include "mruby/ext/io.h"
 
@@ -130,7 +131,7 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass)
   mrb_get_args(mrb, "oo|oooi", &nodename, &service, &family, &socktype, &protocol, &flags);
 
   if (mrb_string_p(nodename)) {
-    hostname = mrb_str_to_cstr(mrb, nodename);
+    hostname = RSTRING_CSTR(mrb, nodename);
   } else if (mrb_nil_p(nodename)) {
     hostname = NULL;
   } else {
@@ -138,9 +139,9 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass)
   }
 
   if (mrb_string_p(service)) {
-    servname = mrb_str_to_cstr(mrb, service);
+    servname = RSTRING_CSTR(mrb, service);
   } else if (mrb_fixnum_p(service)) {
-    servname = mrb_str_to_cstr(mrb, mrb_funcall(mrb, service, "to_s", 0));
+    servname = RSTRING_PTR(mrb_fixnum_to_str(mrb, service, 10));
   } else if (mrb_nil_p(service)) {
     servname = NULL;
   } else {
@@ -170,7 +171,7 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass)
 
   error = getaddrinfo(hostname, servname, &hints, &res0);
   if (error) {
-    mrb_raisef(mrb, E_SOCKET_ERROR, "getaddrinfo: %S", mrb_str_new_cstr(mrb, gai_strerror(error)));
+    mrb_raisef(mrb, E_SOCKET_ERROR, "getaddrinfo: %s", gai_strerror(error));
   }
   mrb_cv_set(mrb, klass, mrb_intern_lit(mrb, "_lastai"), mrb_cptr_value(mrb, res0));
 
@@ -205,7 +206,7 @@ mrb_addrinfo_getnameinfo(mrb_state *mrb, mrb_value self)
   }
   error = getnameinfo((struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr), RSTRING_PTR(host), NI_MAXHOST, RSTRING_PTR(serv), NI_MAXSERV, (int)flags);
   if (error) {
-    mrb_raisef(mrb, E_SOCKET_ERROR, "getnameinfo: %S", mrb_str_new_cstr(mrb, gai_strerror(error)));
+    mrb_raisef(mrb, E_SOCKET_ERROR, "getnameinfo: %s", gai_strerror(error));
   }
   ary = mrb_ary_new_capa(mrb, 2);
   mrb_str_resize(mrb, host, strlen(RSTRING_PTR(host)));
@@ -454,7 +455,7 @@ mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self)
     level = mrb_fixnum(so);
     if (mrb_string_p(optval)) {
       /* that's good */
-    } else if (mrb_type(optval) == MRB_TT_TRUE || mrb_type(optval) == MRB_TT_FALSE) {
+    } else if (mrb_true_p(optval) || mrb_false_p(optval)) {
       mrb_int i = mrb_test(optval) ? 1 : 0;
       optval = mrb_str_new(mrb, (char*)&i, sizeof(i));
     } else if (mrb_fixnum_p(optval)) {
@@ -475,7 +476,7 @@ mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self)
     optname = mrb_fixnum(mrb_funcall(mrb, so, "optname", 0));
     optval = mrb_funcall(mrb, so, "data", 0);
   } else {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 3)", mrb_fixnum_value(argc));
+    mrb_argnum_error(mrb, argc, 3, 3);
   }
 
   s = socket_fd(mrb, self);
@@ -701,7 +702,7 @@ mrb_socket_sockaddr_un(mrb_state *mrb, mrb_value klass)
 
   mrb_get_args(mrb, "S", &path);
   if ((size_t)RSTRING_LEN(path) > sizeof(sunp->sun_path) - 1) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "too long unix socket path (max: %S bytes)", mrb_fixnum_value(sizeof(sunp->sun_path) - 1));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "too long unix socket path (max: %d bytes)", (int)sizeof(sunp->sun_path) - 1);
   }
   s = mrb_str_buf_new(mrb, sizeof(struct sockaddr_un));
   sunp = (struct sockaddr_un *)RSTRING_PTR(s);
index 3017c7c..02eb1e1 100644 (file)
@@ -1,4 +1,3 @@
-#include <stdio.h>
 #include <stdlib.h>
 
 #include "mruby.h"
@@ -8,7 +7,9 @@
 
 #include <io.h>
 
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || \
+    (defined(MRB_MINGW32_VERSION) && MRB_MINGW32_VERSION < 3021) || \
+    (defined(MRB_MINGW64_VERSION) && MRB_MINGW64_VERSION < 4000)
 
 #include <fcntl.h>
 #include <sys/stat.h>
index 946b43a..a0f0a78 100644 (file)
@@ -18,8 +18,8 @@ mrb_mruby_sprintf_gem_init(mrb_state* mrb)
   }
   krn = mrb->kernel_module;
 
-  mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, MRB_ARGS_ANY());
-  mrb_define_method(mrb, krn, "format",  mrb_f_sprintf, MRB_ARGS_ANY());
+  mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, MRB_ARGS_REQ(1)|MRB_ARGS_REST());
+  mrb_define_method(mrb, krn, "format",  mrb_f_sprintf, MRB_ARGS_REQ(1)|MRB_ARGS_REST());
 }
 
 void
index 985ffe2..bf7a4d7 100644 (file)
@@ -5,9 +5,7 @@
 */
 
 #include <mruby.h>
-
 #include <limits.h>
-#include <stdio.h>
 #include <string.h>
 #include <mruby/string.h>
 #include <mruby/hash.h>
@@ -81,7 +79,7 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base)
   char d;
 
   if (base != 2) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base);
   }
   if (val == 0) {
     return mrb_str_new_lit(mrb, "0");
@@ -144,10 +142,10 @@ check_next_arg(mrb_state *mrb, int posarg, int nextarg)
 {
   switch (posarg) {
   case -1:
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with numbered", nextarg);
     break;
   case -2:
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with named", nextarg);
     break;
   default:
     break;
@@ -155,29 +153,29 @@ check_next_arg(mrb_state *mrb, int posarg, int nextarg)
 }
 
 static void
-check_pos_arg(mrb_state *mrb, mrb_int posarg, mrb_int n)
+check_pos_arg(mrb_state *mrb, int posarg, mrb_int n)
 {
   if (posarg > 0) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)",
-               mrb_fixnum_value(n), mrb_fixnum_value(posarg));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%i) after unnumbered(%d)",
+               n, posarg);
   }
   if (posarg == -2) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%i) after named", n);
   }
   if (n < 1) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %i$", n);
   }
 }
 
 static void
-check_name_arg(mrb_state *mrb, int posarg, const char *name, mrb_int len)
+check_name_arg(mrb_state *mrb, int posarg, const char *name, size_t len)
 {
   if (posarg > 0) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after unnumbered(%S)",
-               mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%l after unnumbered(%d)",
+               name, len, posarg);
   }
   if (posarg == -1) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len)));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%l after numbered", name, len);
   }
 }
 
@@ -518,6 +516,50 @@ mrb_f_sprintf(mrb_state *mrb, mrb_value obj)
   }
 }
 
+static int
+mrb_int2str(char *buf, size_t len, mrb_int n)
+{
+#ifdef MRB_DISABLE_STDIO
+  char *bufend = buf + len;
+  char *p = bufend - 1;
+
+  if (len < 1) return -1;
+
+  *p -- = '\0';
+  len --;
+
+  if (n < 0) {
+    if (len < 1) return -1;
+
+    *p -- = '-';
+    len --;
+    n = -n;
+  }
+
+  if (n > 0) {
+    for (; n > 0; len --, n /= 10) {
+      if (len < 1) return -1;
+
+      *p -- = '0' + (n % 10);
+    }
+    p ++;
+  }
+  else if (len > 0) {
+    *p = '0';
+    len --;
+  }
+  else {
+    return -1;
+  }
+
+  memmove(buf, p, bufend - p);
+
+  return bufend - p - 1;
+#else
+  return snprintf(buf, len, "%" MRB_PRId, n);
+#endif /* MRB_DISABLE_STDIO */
+}
+
 mrb_value
 mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fmt)
 {
@@ -580,7 +622,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm
 retry:
     switch (*p) {
       default:
-        mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - \\%%S", mrb_str_new(mrb, p, 1));
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p);
         break;
 
       case ' ':
@@ -619,7 +661,7 @@ retry:
         GETNUM(n, width);
         if (*p == '$') {
           if (!mrb_undef_p(nextvalue)) {
-            mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %S$", mrb_fixnum_value(n));
+            mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %i$", n);
           }
           nextvalue = GETPOSARG(n);
           p++;
@@ -639,14 +681,14 @@ retry:
         for (; p < end && *p != term; )
           p++;
         if (id) {
-          mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%S after <%S>",
-                     mrb_str_new(mrb, start, p - start + 1), mrb_sym2str(mrb, id));
+          mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%l after <%n>",
+                     start, p - start + 1, id);
         }
         symname = mrb_str_new(mrb, start + 1, p - start - 1);
         id = mrb_intern_str(mrb, symname);
-        nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (mrb_int)(p - start + 1));
+        nextvalue = GETNAMEARG(mrb_symbol_value(id), start, p - start + 1);
         if (mrb_undef_p(nextvalue)) {
-          mrb_raisef(mrb, E_KEY_ERROR, "key%S not found", mrb_str_new(mrb, start, p - start + 1));
+          mrb_raisef(mrb, E_KEY_ERROR, "key%l not found", start, p - start + 1);
         }
         if (term == '}') goto format_s;
         p++;
@@ -708,7 +750,12 @@ retry:
         }
         else if (mrb_fixnum_p(val)) {
           mrb_int n = mrb_fixnum(val);
+#ifndef MRB_UTF8_STRING
+          char buf[1];
 
+          buf[0] = (char)n&0xff;
+          tmp = mrb_str_new(mrb, buf, 1);
+#else
           if (n < 0x80) {
             char buf[1];
 
@@ -719,6 +766,7 @@ retry:
             tmp = mrb_funcall(mrb, val, "chr", 0);
             mrb_check_type(mrb, tmp, MRB_TT_STRING);
           }
+#endif
         }
         else {
           mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character");
@@ -794,7 +842,7 @@ retry:
       case 'B':
       case 'u': {
         mrb_value val = GETARG();
-        char nbuf[68], *s;
+        char nbuf[69], *s;
         const char *prefix = NULL;
         int sign = 0, dots = 0;
         char sc = 0;
@@ -845,6 +893,7 @@ retry:
           case 'd':
           case 'i':
             sign = 1;
+            /* fall through */
           default:
             base = 10; break;
         }
@@ -865,7 +914,7 @@ retry:
             width--;
           }
           mrb_assert(base == 10);
-          snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v);
+          mrb_int2str(nbuf, sizeof(nbuf)-1, v);
           s = nbuf;
           if (v < 0) s++;       /* skip minus sign */
         }
@@ -873,24 +922,12 @@ retry:
           s = nbuf;
           if (v < 0) {
             dots = 1;
+            val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);
           }
-          switch (base) {
-          case 2:
-            if (v < 0) {
-              val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);
-            }
-            else {
-              val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);
-            }
-            strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1);
-            break;
-          case 8:
-            snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v);
-            break;
-          case 16:
-            snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIx, v);
-            break;
+          else {
+            val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);
           }
+          strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-2);
           if (v < 0) {
             char d;
 
@@ -1003,10 +1040,8 @@ retry:
       case 'A': {
         mrb_value val = GETARG();
         double fval;
-        mrb_int i;
         mrb_int need = 6;
-        char fbuf[32];
-        int frexp_result;
+        char fbuf[64];
 
         fval = mrb_float(mrb_Float(mrb, val));
         if (!isfinite(fval)) {
@@ -1047,12 +1082,10 @@ retry:
           break;
         }
 
-        fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
         need = 0;
         if (*p != 'e' && *p != 'E') {
-          i = INT_MIN;
-          frexp(fval, &frexp_result);
-          i = (mrb_int)frexp_result;
+          int i;
+          frexp(fval, &i);
           if (i > 0)
             need = BIT_DIGITS(i);
         }
@@ -1070,7 +1103,8 @@ retry:
         need += 20;
 
         CHECK(need);
-        n = snprintf(&buf[blen], need, fbuf, fval);
+        fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
+        n = mrb_float_to_cstr(mrb, &buf[blen], need, fbuf, fval);
         if (n < 0 || n >= need) {
           mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error");
         }
@@ -1089,7 +1123,7 @@ retry:
   if (posarg >= 0 && nextarg < argc) {
     const char *mesg = "too many arguments for format string";
     if (mrb_test(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, mesg);
-    if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%S", mrb_str_new_cstr(mrb, mesg));
+    if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%s", mesg);
   }
 #endif
   mrb_str_resize(mrb, result, blen);
@@ -1112,12 +1146,13 @@ fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec)
   if (flags & FSPACE) *buf++ = ' ';
 
   if (flags & FWIDTH) {
-    n = snprintf(buf, end - buf, "%d", (int)width);
+    n = mrb_int2str(buf, end - buf, width);
     buf += n;
   }
 
   if (flags & FPREC) {
-    n = snprintf(buf, end - buf, ".%d", (int)prec);
+    *buf ++ = '.';
+    n = mrb_int2str(buf, end - buf, prec);
     buf += n;
   }
 
index 137812a..0eb51f5 100644 (file)
@@ -8,6 +8,11 @@ assert('String#%') do
   assert_equal 15, ("%b" % (1<<14)).size
   skip unless Object.const_defined?(:Float)
   assert_equal "1.0", "%3.1f" % 1.01
+  assert_equal " 123456789.12", "% 4.2f" % 123456789.123456789
+  assert_equal "123456789.12", "%-4.2f" % 123456789.123456789
+  assert_equal "+123456789.12", "%+4.2f" % 123456789.123456789
+  assert_equal "123456789.12", "%04.2f" % 123456789.123456789
+  assert_equal "00000000123456789.12", "%020.2f" % 123456789.123456789
 end
 
 assert('String#% with inf') do
@@ -68,29 +73,6 @@ assert('String#% with nan') do
   assert_equal "  NaN", "% 5f" % nan
 end
 
-assert("String#% with invalid chr") do
-  begin
-    class Fixnum
-      alias_method :chr_, :chr if method_defined?(:chr)
-
-      def chr
-        nil
-      end
-    end
-
-    assert_raise TypeError do
-      "%c" % 0x80
-    end
-  ensure
-    class Fixnum
-      if method_defined?(:chr_)
-        alias_method :chr, :chr_
-        remove_method :chr_
-      end
-    end
-  end
-end
-
 assert("String#% %b") do
   assert_equal("..10115", "%0b5" % -5)
 end
index 9812f2c..f2df5a7 100644 (file)
@@ -2,5 +2,4 @@ MRuby::Gem::Specification.new('mruby-string-ext') do |spec|
   spec.license = 'MIT'
   spec.author  = 'mruby developers'
   spec.summary = 'String class extension'
-  spec.add_test_dependency 'mruby-enumerator', core: 'mruby-enumerator'
 end
index 311803e..e57d753 100644 (file)
@@ -310,11 +310,15 @@ class String
     end
   end
 
+  ##
+  # Call the given block for each character of
+  # +self+.
   def each_char(&block)
     return to_enum :each_char unless block
-
-    split('').each do |i|
-      block.call(i)
+    pos = 0
+    while pos < self.size
+      block.call(self[pos])
+      pos += 1
     end
     self
   end
@@ -410,7 +414,7 @@ class String
       e = max.ord
       while c <= e
         break if exclusive and c == e
-        yield c.chr
+        yield c.chr(__ENCODING__)
         c += 1
       end
       return self
index ba7e3c6..7cf146e 100644 (file)
@@ -5,82 +5,90 @@
 #include <mruby/string.h>
 #include <mruby/range.h>
 
-static mrb_value
-mrb_str_getbyte(mrb_state *mrb, mrb_value str)
-{
-  mrb_int pos;
-  mrb_get_args(mrb, "i", &pos);
+#define ENC_ASCII_8BIT "ASCII-8BIT"
+#define ENC_BINARY     "BINARY"
+#define ENC_UTF8       "UTF-8"
 
-  if (pos < 0)
-    pos += RSTRING_LEN(str);
-  if (pos < 0 ||  RSTRING_LEN(str) <= pos)
-    return mrb_nil_value();
+#define ENC_COMP_P(enc, enc_lit) \
+  str_casecmp_p(RSTRING_PTR(enc), RSTRING_LEN(enc), enc_lit, sizeof(enc_lit"")-1)
+
+#ifdef MRB_WITHOUT_FLOAT
+# define mrb_float_p(o) FALSE
+#endif
 
-  return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]);
+static mrb_bool
+str_casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2)
+{
+  const char *e1, *e2;
+
+  if (len1 != len2) return FALSE;
+  e1 = s1 + len1;
+  e2 = s2 + len2;
+  while (s1 < e1 && s2 < e2) {
+    if (*s1 != *s2 && TOUPPER(*s1) != TOUPPER(*s2)) return FALSE;
+    ++s1;
+    ++s2;
+  }
+  return TRUE;
 }
 
 static mrb_value
-mrb_str_setbyte(mrb_state *mrb, mrb_value str)
+int_chr_binary(mrb_state *mrb, mrb_value num)
 {
-  mrb_int pos, byte;
-  mrb_int len;
-
-  mrb_get_args(mrb, "ii", &pos, &byte);
-
-  len = RSTRING_LEN(str);
-  if (pos < -len || len <= pos)
-    mrb_raisef(mrb, E_INDEX_ERROR, "index %S is out of array", mrb_fixnum_value(pos));
-  if (pos < 0)
-    pos += len;
+  mrb_int cp = mrb_int(mrb, num);
+  char c;
+  mrb_value str;
 
-  mrb_str_modify(mrb, mrb_str_ptr(str));
-  byte &= 0xff;
-  RSTRING_PTR(str)[pos] = (unsigned char)byte;
-  return mrb_fixnum_value((unsigned char)byte);
+  if (cp < 0 || 0xff < cp) {
+    mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num);
+  }
+  c = (char)cp;
+  str = mrb_str_new(mrb, &c, 1);
+  RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+  return str;
 }
 
+#ifdef MRB_UTF8_STRING
 static mrb_value
-mrb_str_byteslice(mrb_state *mrb, mrb_value str)
+int_chr_utf8(mrb_state *mrb, mrb_value num)
 {
-  mrb_value a1;
+  mrb_int cp = mrb_int(mrb, num);
+  char utf8[4];
   mrb_int len;
+  mrb_value str;
+  uint32_t ascii_flag = 0;
 
-  if (mrb_get_argc(mrb) == 2) {
-    mrb_int pos;
-    mrb_get_args(mrb, "ii", &pos, &len);
-    return mrb_str_substr(mrb, str, pos, len);
+  if (cp < 0 || 0x10FFFF < cp) {
+    mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num);
   }
-  mrb_get_args(mrb, "o|i", &a1, &len);
-  switch (mrb_type(a1)) {
-  case MRB_TT_RANGE:
-    {
-      mrb_int beg;
-
-      len = RSTRING_LEN(str);
-      switch (mrb_range_beg_len(mrb, a1, &beg, &len, len, TRUE)) {
-      case 0:                   /* not range */
-        break;
-      case 1:                   /* range */
-        return mrb_str_substr(mrb, str, beg, len);
-      case 2:                   /* out of range */
-        mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", a1);
-        break;
-      }
-      return mrb_nil_value();
-    }
-#ifndef MRB_WITHOUT_FLOAT
-  case MRB_TT_FLOAT:
-    a1 = mrb_fixnum_value((mrb_int)mrb_float(a1));
-    /* fall through */
-#endif
-  case MRB_TT_FIXNUM:
-    return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1);
-  default:
-    mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument");
+  if (cp < 0x80) {
+    utf8[0] = (char)cp;
+    len = 1;
+    ascii_flag = MRB_STR_ASCII;
   }
-  /* not reached */
-  return mrb_nil_value();
+  else if (cp < 0x800) {
+    utf8[0] = (char)(0xC0 | (cp >> 6));
+    utf8[1] = (char)(0x80 | (cp & 0x3F));
+    len = 2;
+  }
+  else if (cp < 0x10000) {
+    utf8[0] = (char)(0xE0 |  (cp >> 12));
+    utf8[1] = (char)(0x80 | ((cp >>  6) & 0x3F));
+    utf8[2] = (char)(0x80 | ( cp        & 0x3F));
+    len = 3;
+  }
+  else {
+    utf8[0] = (char)(0xF0 |  (cp >> 18));
+    utf8[1] = (char)(0x80 | ((cp >> 12) & 0x3F));
+    utf8[2] = (char)(0x80 | ((cp >>  6) & 0x3F));
+    utf8[3] = (char)(0x80 | ( cp        & 0x3F));
+    len = 4;
+  }
+  str = mrb_str_new(mrb, utf8, len);
+  mrb_str_ptr(str)->flags |= ascii_flag;
+  return str;
 }
+#endif
 
 /*
  *  call-seq:
@@ -137,8 +145,6 @@ mrb_str_swapcase(mrb_state *mrb, mrb_value self)
   return str;
 }
 
-static mrb_value mrb_fixnum_chr(mrb_state *mrb, mrb_value num);
-
 /*
  *  call-seq:
  *     str << integer       -> str
@@ -148,7 +154,8 @@ static mrb_value mrb_fixnum_chr(mrb_state *mrb, mrb_value num);
  *
  *  Append---Concatenates the given object to <i>str</i>. If the object is a
  *  <code>Integer</code>, it is considered as a codepoint, and is converted
- *  to a character before concatenation.
+ *  to a character before concatenation
+ *  (equivalent to <code>str.concat(integer.chr(__ENCODING__))</code>).
  *
  *     a = "hello "
  *     a << "world"   #=> "hello world"
@@ -157,14 +164,17 @@ static mrb_value mrb_fixnum_chr(mrb_state *mrb, mrb_value num);
 static mrb_value
 mrb_str_concat_m(mrb_state *mrb, mrb_value self)
 {
-  mrb_value str;
+  mrb_value str = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &str);
-  if (mrb_fixnum_p(str))
-    str = mrb_fixnum_chr(mrb, str);
+  if (mrb_fixnum_p(str) || mrb_float_p(str))
+#ifdef MRB_UTF8_STRING
+    str = int_chr_utf8(mrb, str);
+#else
+    str = int_chr_binary(mrb, str);
+#endif
   else
-    str = mrb_ensure_string_type(mrb, str);
-  mrb_str_concat(mrb, self, str);
+    mrb_ensure_string_type(mrb, str);
+  mrb_str_cat_str(mrb, self, str);
   return self;
 }
 
@@ -324,7 +334,7 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte
 
       len = i - start_pos;
       if (len > UINT16_MAX) {
-        mrb_raise(mrb, E_ARGUMENT_ERROR, "tr pattern too long (max 65536)");
+        mrb_raise(mrb, E_ARGUMENT_ERROR, "tr pattern too long (max 65535)");
       }
       if (pat1 == NULL && ret) {
         goto nomem;
@@ -332,9 +342,9 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte
       pat1->type = TR_IN_ORDER;
       pat1->flag_reverse = flag_reverse;
       pat1->flag_on_heap = !ret_uninit;
-      pat1->n = len;
+      pat1->n = (uint16_t)len;
       pat1->next = NULL;
-      pat1->val.start_pos = start_pos;
+      pat1->val.start_pos = (uint16_t)start_pos;
     }
 
     if (ret == NULL || ret_uninit) {
@@ -507,8 +517,7 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee
           continue;
         }
         if (c > 0x80) {
-          mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%S) out of range",
-                     mrb_fixnum_value((mrb_int)c));
+          mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%i) out of range", c);
         }
        lastch = c;
        s[i] = (char)c;
@@ -812,7 +821,7 @@ mrb_str_count(mrb_state *mrb, mrb_value str)
   tr_parse_pattern(mrb, &pat, v_pat, TRUE);
   tr_compile_pattern(&pat, v_pat, bitmap);
   tr_free_pattern(mrb, &pat);
-  
+
   s = RSTRING_PTR(str);
   len = RSTRING_LEN(str);
   for (i = 0; i < len; i++) {
@@ -848,49 +857,42 @@ mrb_str_chr(mrb_state *mrb, mrb_value self)
   return mrb_str_substr(mrb, self, 0, 1);
 }
 
+/*
+ *  call-seq:
+ *     int.chr([encoding])  ->  string
+ *
+ *  Returns a string containing the character represented by the +int+'s value
+ *  according to +encoding+. +"ASCII-8BIT"+ (+"BINARY"+) and +"UTF-8"+ (only
+ *  with +MRB_UTF8_STRING+) can be specified as +encoding+ (default is
+ *  +"ASCII-8BIT"+).
+ *
+ *     65.chr                  #=> "A"
+ *     230.chr                 #=> "\xE6"
+ *     230.chr("ASCII-8BIT")   #=> "\xE6"
+ *     230.chr("UTF-8")        #=> "\u00E6"
+ */
 static mrb_value
-mrb_fixnum_chr(mrb_state *mrb, mrb_value num)
+mrb_int_chr(mrb_state *mrb, mrb_value num)
 {
-  mrb_int cp = mrb_fixnum(num);
-#ifdef MRB_UTF8_STRING
-  char utf8[4];
-  mrb_int len;
-
-  if (cp < 0 || 0x10FFFF < cp) {
-    mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num);
-  }
-  if (cp < 0x80) {
-    utf8[0] = (char)cp;
-    len = 1;
-  }
-  else if (cp < 0x800) {
-    utf8[0] = (char)(0xC0 | (cp >> 6));
-    utf8[1] = (char)(0x80 | (cp & 0x3F));
-    len = 2;
+  mrb_value enc;
+  mrb_bool enc_given;
+
+  mrb_get_args(mrb, "|S?", &enc, &enc_given);
+  if (!enc_given ||
+      ENC_COMP_P(enc, ENC_ASCII_8BIT) ||
+      ENC_COMP_P(enc, ENC_BINARY)) {
+    return int_chr_binary(mrb, num);
   }
-  else if (cp < 0x10000) {
-    utf8[0] = (char)(0xE0 |  (cp >> 12));
-    utf8[1] = (char)(0x80 | ((cp >>  6) & 0x3F));
-    utf8[2] = (char)(0x80 | ( cp        & 0x3F));
-    len = 3;
+#ifdef MRB_UTF8_STRING
+  else if (ENC_COMP_P(enc, ENC_UTF8)) {
+    return int_chr_utf8(mrb, num);
   }
+#endif
   else {
-    utf8[0] = (char)(0xF0 |  (cp >> 18));
-    utf8[1] = (char)(0x80 | ((cp >> 12) & 0x3F));
-    utf8[2] = (char)(0x80 | ((cp >>  6) & 0x3F));
-    utf8[3] = (char)(0x80 | ( cp        & 0x3F));
-    len = 4;
-  }
-  return mrb_str_new(mrb, utf8, len);
-#else
-  char c;
-
-  if (cp < 0 || 0xff < cp) {
-    mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num);
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown encoding name - %v", enc);
   }
-  c = (char)cp;
-  return mrb_str_new(mrb, &c, 1);
-#endif
+  /* not reached */
+  return mrb_nil_value();
 }
 
 /*
@@ -1078,7 +1080,7 @@ mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self)
   if (plen > slen) return mrb_nil_value();
   s = RSTR_PTR(str);
   if (memcmp(s, ptr, plen) != 0) return mrb_nil_value();
-  if (!MRB_FROZEN_P(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
+  if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
     str->as.heap.ptr += plen;
   }
   else {
@@ -1135,7 +1137,7 @@ mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self)
   if (plen > slen) return mrb_nil_value();
   s = RSTR_PTR(str);
   if (memcmp(s+slen-plen, ptr, plen) != 0) return mrb_nil_value();
-  if (!MRB_FROZEN_P(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
+  if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
     /* no need to modify string */
   }
   else {
@@ -1178,8 +1180,6 @@ mrb_str_lines(mrb_state *mrb, mrb_value self)
   char *p = b, *t;
   char *e = b + RSTRING_LEN(self);
 
-  mrb_get_args(mrb, "");
-
   result = mrb_ary_new(mrb);
   ai = mrb_gc_arena_save(mrb);
   while (p < e) {
@@ -1199,9 +1199,6 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
   struct RClass * s = mrb->string_class;
 
   mrb_define_method(mrb, s, "dump",            mrb_str_dump,            MRB_ARGS_NONE());
-  mrb_define_method(mrb, s, "getbyte",         mrb_str_getbyte,         MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, s, "setbyte",         mrb_str_setbyte,         MRB_ARGS_REQ(2));
-  mrb_define_method(mrb, s, "byteslice",       mrb_str_byteslice,       MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
   mrb_define_method(mrb, s, "swapcase!",       mrb_str_swapcase_bang,   MRB_ARGS_NONE());
   mrb_define_method(mrb, s, "swapcase",        mrb_str_swapcase,        MRB_ARGS_NONE());
   mrb_define_method(mrb, s, "concat",          mrb_str_concat_m,        MRB_ARGS_REQ(1));
@@ -1222,8 +1219,8 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
   mrb_define_method(mrb, s, "chr",             mrb_str_chr,             MRB_ARGS_NONE());
   mrb_define_method(mrb, s, "succ",            mrb_str_succ,            MRB_ARGS_NONE());
   mrb_define_method(mrb, s, "succ!",           mrb_str_succ_bang,       MRB_ARGS_NONE());
-  mrb_define_alias(mrb,  s, "next",            "succ");
-  mrb_define_alias(mrb,  s, "next!",           "succ!");
+  mrb_define_method(mrb, s, "next",            mrb_str_succ,            MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "next!",           mrb_str_succ_bang,       MRB_ARGS_NONE());
   mrb_define_method(mrb, s, "ord",             mrb_str_ord,             MRB_ARGS_NONE());
   mrb_define_method(mrb, s, "delete_prefix!",  mrb_str_del_prefix_bang, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, s, "delete_prefix",   mrb_str_del_prefix,      MRB_ARGS_REQ(1));
@@ -1231,7 +1228,8 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
   mrb_define_method(mrb, s, "delete_suffix",   mrb_str_del_suffix,      MRB_ARGS_REQ(1));
 
   mrb_define_method(mrb, s, "__lines",         mrb_str_lines,           MRB_ARGS_NONE());
-  mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE());
+
+  mrb_define_method(mrb, mrb_module_get(mrb, "Integral"), "chr", mrb_int_chr, MRB_ARGS_OPT(1));
 }
 
 void
diff --git a/third-party/mruby/mrbgems/mruby-string-ext/test/numeric.rb b/third-party/mruby/mrbgems/mruby-string-ext/test/numeric.rb
new file mode 100644 (file)
index 0000000..dfcb9eb
--- /dev/null
@@ -0,0 +1,29 @@
+# coding: utf-8
+
+assert('Integer#chr') do
+  assert_equal("A", 65.chr)
+  assert_equal("B", 0x42.chr)
+  assert_equal("\xab", 171.chr)
+  assert_raise(RangeError) { -1.chr }
+  assert_raise(RangeError) { 256.chr }
+
+  assert_equal("A", 65.chr("ASCII-8BIT"))
+  assert_equal("B", 0x42.chr("BINARY"))
+  assert_equal("\xab", 171.chr("ascii-8bit"))
+  assert_raise(RangeError) { -1.chr("binary") }
+  assert_raise(RangeError) { 256.chr("Ascii-8bit") }
+  assert_raise(ArgumentError) { 65.chr("ASCII") }
+  assert_raise(ArgumentError) { 65.chr("ASCII-8BIT", 2) }
+  assert_raise(TypeError) { 65.chr(:BINARY) }
+
+  if __ENCODING__ == "ASCII-8BIT"
+    assert_raise(ArgumentError) { 65.chr("UTF-8") }
+  else
+    assert_equal("A", 65.chr("UTF-8"))
+    assert_equal("B", 0x42.chr("UTF-8"))
+    assert_equal("«", 171.chr("utf-8"))
+    assert_equal("あ", 12354.chr("Utf-8"))
+    assert_raise(RangeError) { -1.chr("utf-8") }
+    assert_raise(RangeError) { 0x110000.chr.chr("UTF-8") }
+  end
+end
diff --git a/third-party/mruby/mrbgems/mruby-string-ext/test/range.rb b/third-party/mruby/mrbgems/mruby-string-ext/test/range.rb
new file mode 100644 (file)
index 0000000..80c2868
--- /dev/null
@@ -0,0 +1,26 @@
+assert('Range#max') do
+  # returns the maximum value in the range when called with no arguments
+  assert_equal 'l', ('f'..'l').max
+  assert_equal 'e', ('a'...'f').max
+
+  # returns nil when the endpoint is less than the start point
+  assert_equal nil, ('z'..'l').max
+end
+
+assert('Range#max given a block') do
+  # returns nil when the endpoint is less than the start point
+  assert_equal nil, (('z'..'l').max { |x, y| x <=> y })
+end
+
+assert('Range#min') do
+  # returns the minimum value in the range when called with no arguments
+  assert_equal 'f', ('f'..'l').min
+
+  # returns nil when the start point is greater than the endpoint
+  assert_equal nil, ('z'..'l').min
+end
+
+assert('Range#min given a block') do
+  # returns nil when the start point is greater than the endpoint
+  assert_equal nil, (('z'..'l').min { |x, y| x <=> y })
+end
index 44ca1fd..3f11c00 100644 (file)
@@ -2,39 +2,18 @@
 ##
 # String(Ext) Test
 
-UTF8STRING = ("\343\201\202".size == 1)
+UTF8STRING = __ENCODING__ == "UTF-8"
 
-assert('String#getbyte') do
-  str1 = "hello"
-  bytes1 = [104, 101, 108, 108, 111]
-  assert_equal bytes1[0], str1.getbyte(0)
-  assert_equal bytes1[-1], str1.getbyte(-1)
-  assert_equal bytes1[6], str1.getbyte(6)
-
-  str2 = "\xFF"
-  bytes2 = [0xFF]
-  assert_equal bytes2[0], str2.getbyte(0)
-end
-
-assert('String#setbyte') do
-  str1 = "hello"
-  h = "H".getbyte(0)
-  str1.setbyte(0, h)
-  assert_equal(h, str1.getbyte(0))
-  assert_equal("Hello", str1)
-end
-
-assert('String#byteslice') do
-  str1 = "hello"
-  assert_equal("e", str1.byteslice(1))
-  assert_equal("o", str1.byteslice(-1))
-  assert_equal("ell", str1.byteslice(1..3))
-  assert_equal("el", str1.byteslice(1...3))
+def assert_upto(exp, receiver, *args)
+  act = []
+  receiver.upto(*args) { |v| act << v }
+  assert_equal exp, act
 end
 
 assert('String#dump') do
   assert_equal("\"\\x00\"", "\0".dump)
   assert_equal("\"foo\"", "foo".dump)
+  assert_equal('"\xe3\x82\x8b"', "る".dump)
   assert_nothing_raised { ("\1" * 100).dump }   # regress #1210
 end
 
@@ -116,8 +95,15 @@ end
 assert('String#concat') do
   assert_equal "Hello World!", "Hello " << "World" << 33
   assert_equal "Hello World!", "Hello ".concat("World").concat(33)
-
   assert_raise(TypeError) { "".concat(Object.new) }
+
+  if UTF8STRING
+    assert_equal "H«", "H" << 0xab
+    assert_equal "Hは", "H" << 12399
+  else
+    assert_equal "H\xab", "H" << 0xab
+    assert_raise(RangeError) { "H" << 12399 }
+  end
 end
 
 assert('String#casecmp') do
@@ -247,12 +233,6 @@ assert('String#oct') do
   assert_equal (-8), "-10".oct
 end
 
-assert('String#chr') do
-  assert_equal "a", "abcde".chr
-  # test Fixnum#chr as well
-  assert_equal "a", 97.chr
-end
-
 assert('String#lines') do
   assert_equal ["Hel\n", "lo\n", "World!"], "Hel\nlo\nWorld!".lines
   assert_equal ["Hel\n", "lo\n", "World!\n"], "Hel\nlo\nWorld!\n".lines
@@ -539,16 +519,15 @@ assert('String#rjust should raise on zero width padding') do
 end
 
 assert('String#upto') do
-  assert_equal %w(a8 a9 b0 b1 b2 b3 b4 b5 b6), "a8".upto("b6").to_a
-  assert_equal ["9", "10", "11"], "9".upto("11").to_a
-  assert_equal [], "25".upto("5").to_a
-  assert_equal ["07", "08", "09", "10", "11"], "07".upto("11").to_a
-
-if UTF8STRING
-  assert_equal ["あ", "ぃ", "い", "ぅ", "う", "ぇ", "え", "ぉ", "お"], "あ".upto("お").to_a
-end
-
-  assert_equal ["9", ":", ";", "<", "=", ">", "?", "@", "A"], "9".upto("A").to_a
+  assert_upto %w(a8 a9 b0 b1 b2 b3 b4 b5 b6), "a8", "b6"
+  assert_upto ["9", "10", "11"], "9", "11"
+  assert_upto [], "25", "5"
+  assert_upto ["07", "08", "09", "10", "11"], "07", "11"
+  assert_upto ["9", ":", ";", "<", "=", ">", "?", "@", "A"], "9", "A"
+
+  if UTF8STRING
+    assert_upto %w(あ ぃ い ぅ う ぇ え ぉ お), "あ", "お"
+  end
 
   a     = "aa"
   start = "aa"
@@ -630,8 +609,11 @@ assert('String#ord(UTF-8)') do
 end if UTF8STRING
 
 assert('String#chr') do
+  assert_equal "a", "abcde".chr
   assert_equal "h", "hello!".chr
+  assert_equal "", "".chr
 end
+
 assert('String#chr(UTF-8)') do
   assert_equal "こ", "こんにちは世界!".chr
 end if UTF8STRING
@@ -657,19 +639,19 @@ assert('String#chars(UTF-8)') do
 end if UTF8STRING
 
 assert('String#each_char') do
-  s = ""
+  chars = []
   "hello!".each_char do |x|
-    s += x
+    chars << x
   end
-  assert_equal "hello!", s
+  assert_equal ["h", "e", "l", "l", "o", "!"], chars
 end
 
 assert('String#each_char(UTF-8)') do
-  s = ""
+  chars = []
   "こんにちは世界!".each_char do |x|
-    s += x
+    chars << x
   end
-  assert_equal "こんにちは世界!", s
+  assert_equal ["こ", "ん", "に", "ち", "は", "世", "界", "!"], chars
 end if UTF8STRING
 
 assert('String#codepoints') do
index c5b5354..21cbb47 100644 (file)
@@ -46,7 +46,9 @@ if Object.const_defined?(:Struct)
       ary
     end
 
-    def _inspect
+    def _inspect(recur_list)
+      return "#<struct #{self.class}:...>" if recur_list[self.object_id]
+      recur_list[self.object_id] = true
       name = self.class.to_s
       if name[0] == "#"
         str = "#<struct "
@@ -55,7 +57,7 @@ if Object.const_defined?(:Struct)
       end
       buf = []
       self.each_pair do |k,v|
-        buf.push [k.to_s + "=" + v._inspect]
+        buf.push k.to_s + "=" + v._inspect(recur_list)
       end
       str + buf.join(", ") + ">"
     end
@@ -70,11 +72,7 @@ if Object.const_defined?(:Struct)
     # 15.2.18.4.10(x)
     #
     def inspect
-      begin
-        self._inspect
-      rescue SystemStackError
-        "#<struct #{self.class.to_s}:...>"
-      end
+      self._inspect({})
     end
 
     ##
index c0ce712..7fbf922 100644 (file)
@@ -66,8 +66,8 @@ struct_members(mrb_state *mrb, mrb_value s)
     }
     else {
       mrb_raisef(mrb, E_TYPE_ERROR,
-                 "struct size differs (%S required %S given)",
-                 mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s)));
+                 "struct size differs (%i required %i given)",
+                 RARRAY_LEN(members), RSTRUCT_LEN(s));
     }
   }
   return members;
@@ -87,10 +87,7 @@ mrb_struct_s_members_m(mrb_state *mrb, mrb_value klass)
 static void
 mrb_struct_modify(mrb_state *mrb, mrb_value strct)
 {
-  if (MRB_FROZEN_P(mrb_basic_ptr(strct))) {
-    mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen struct");
-  }
-
+  mrb_check_frozen(mrb, mrb_basic_ptr(strct));
   mrb_write_barrier(mrb, mrb_basic_ptr(strct));
 }
 
@@ -126,19 +123,29 @@ mrb_struct_ref(mrb_state *mrb, mrb_value obj)
 static mrb_sym
 mrb_id_attrset(mrb_state *mrb, mrb_sym id)
 {
+#define ONSTACK_ALLOC_MAX 32
+#define ONSTACK_STRLEN_MAX (ONSTACK_ALLOC_MAX - 1) /* '=' character */
+
   const char *name;
   char *buf;
   mrb_int len;
   mrb_sym mid;
+  char onstack[ONSTACK_ALLOC_MAX];
 
-  name = mrb_sym2name_len(mrb, id, &len);
-  buf = (char *)mrb_malloc(mrb, (size_t)len+2);
+  name = mrb_sym_name_len(mrb, id, &len);
+  if (len > ONSTACK_STRLEN_MAX) {
+    buf = (char *)mrb_malloc(mrb, (size_t)len+1);
+  }
+  else {
+    buf = onstack;
+  }
   memcpy(buf, name, (size_t)len);
   buf[len] = '=';
-  buf[len+1] = '\0';
 
   mid = mrb_intern(mrb, buf, len+1);
-  mrb_free(mrb, buf);
+  if (buf != onstack) {
+    mrb_free(mrb, buf);
+  }
   return mid;
 }
 
@@ -147,9 +154,8 @@ mrb_struct_set_m(mrb_state *mrb, mrb_value obj)
 {
   mrb_int i = mrb_fixnum(mrb_proc_cfunc_env_get(mrb, 0));
   mrb_value *ptr;
-  mrb_value val;
+  mrb_value val = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &val);
   mrb_struct_modify(mrb, obj);
   ptr = RSTRUCT_PTR(obj);
   if (ptr == NULL || i >= RSTRUCT_LEN(obj)) {
@@ -161,20 +167,6 @@ mrb_struct_set_m(mrb_state *mrb, mrb_value obj)
   return val;
 }
 
-static mrb_bool
-is_local_id(mrb_state *mrb, const char *name)
-{
-  if (!name) return FALSE;
-  return !ISUPPER(name[0]);
-}
-
-static mrb_bool
-is_const_id(mrb_state *mrb, const char *name)
-{
-  if (!name) return FALSE;
-  return ISUPPER(name[0]);
-}
-
 static void
 make_struct_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c)
 {
@@ -185,19 +177,15 @@ make_struct_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c
 
   for (i=0; i<len; i++) {
     mrb_sym id = mrb_symbol(ptr_members[i]);
-    const char *name = mrb_sym2name_len(mrb, id, NULL);
-
-    if (is_local_id(mrb, name) || is_const_id(mrb, name)) {
-      mrb_method_t m;
-      mrb_value at = mrb_fixnum_value(i);
-      struct RProc *aref = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_ref, 1, &at);
-      struct RProc *aset = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_set_m, 1, &at);
-      MRB_METHOD_FROM_PROC(m, aref);
-      mrb_define_method_raw(mrb, c, id, m);
-      MRB_METHOD_FROM_PROC(m, aset);
-      mrb_define_method_raw(mrb, c, mrb_id_attrset(mrb, id), m);
-      mrb_gc_arena_restore(mrb, ai);
-    }
+    mrb_method_t m;
+    mrb_value at = mrb_fixnum_value(i);
+    struct RProc *aref = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_ref, 1, &at);
+    struct RProc *aset = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_set_m, 1, &at);
+    MRB_METHOD_FROM_PROC(m, aref);
+    mrb_define_method_raw(mrb, c, id, m);
+    MRB_METHOD_FROM_PROC(m, aset);
+    mrb_define_method_raw(mrb, c, mrb_id_attrset(mrb, id), m);
+    mrb_gc_arena_restore(mrb, ai);
   }
 }
 
@@ -215,11 +203,11 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl
     /* old style: should we warn? */
     mrb_to_str(mrb, name);
     id = mrb_obj_to_sym(mrb, name);
-    if (!is_const_id(mrb, mrb_sym2name_len(mrb, id, NULL))) {
-      mrb_name_error(mrb, id, "identifier %S needs to be constant", name);
+    if (!mrb_const_name_p(mrb, RSTRING_PTR(name), RSTRING_LEN(name))) {
+      mrb_name_error(mrb, id, "identifier %v needs to be constant", name);
     }
     if (mrb_const_defined_at(mrb, mrb_obj_value(klass), id)) {
-      mrb_warn(mrb, "redefining constant Struct::%S", name);
+      mrb_warn(mrb, "redefining constant Struct::%v", name);
       mrb_const_remove(mrb, mrb_obj_value(klass), id);
     }
     c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass);
@@ -285,7 +273,7 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass)
   name = mrb_nil_value();
   mrb_get_args(mrb, "*&", &argv, &argc, &b);
   if (argc == 0) { /* special case to avoid crash */
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
+    mrb_argnum_error(mrb, argc, 1, -1);
   }
   else {
     pargv = argv;
@@ -367,9 +355,7 @@ mrb_struct_initialize(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_struct_init_copy(mrb_state *mrb, mrb_value copy)
 {
-  mrb_value s;
-
-  mrb_get_args(mrb, "o", &s);
+  mrb_value s = mrb_get_arg1(mrb);
 
   if (mrb_obj_equal(mrb, copy, s)) return copy;
   if (!mrb_obj_is_instance_of(mrb, s, mrb_obj_class(mrb, copy))) {
@@ -399,23 +385,22 @@ struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id)
       return ptr[i];
     }
   }
-  mrb_name_error(mrb, id, "no member '%S' in struct", mrb_sym2str(mrb, id));
+  mrb_name_error(mrb, id, "no member '%n' in struct", id);
   return mrb_nil_value();       /* not reached */
 }
 
 static mrb_value
 struct_aref_int(mrb_state *mrb, mrb_value s, mrb_int i)
 {
-  if (i < 0) i = RSTRUCT_LEN(s) + i;
-  if (i < 0)
-      mrb_raisef(mrb, E_INDEX_ERROR,
-                 "offset %S too small for struct(size:%S)",
-                 mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
-  if (RSTRUCT_LEN(s) <= i)
+  mrb_int idx = i < 0 ? RSTRUCT_LEN(s) + i : i;
+
+  if (idx < 0)
     mrb_raisef(mrb, E_INDEX_ERROR,
-               "offset %S too large for struct(size:%S)",
-               mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
-  return RSTRUCT_PTR(s)[i];
+               "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s));
+  if (RSTRUCT_LEN(s) <= idx)
+    mrb_raisef(mrb, E_INDEX_ERROR,
+               "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s));
+  return RSTRUCT_PTR(s)[idx];
 }
 
 /* 15.2.18.4.2  */
@@ -440,14 +425,13 @@ struct_aref_int(mrb_state *mrb, mrb_value s, mrb_int i)
 static mrb_value
 mrb_struct_aref(mrb_state *mrb, mrb_value s)
 {
-  mrb_value idx;
+  mrb_value idx = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &idx);
   if (mrb_string_p(idx)) {
     mrb_value sym = mrb_check_intern_str(mrb, idx);
 
     if (mrb_nil_p(sym)) {
-      mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx);
+      mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%v' in struct", idx);
     }
     idx = sym;
   }
@@ -475,7 +459,7 @@ mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val)
       return val;
     }
   }
-  mrb_name_error(mrb, id, "no member '%S' in struct", mrb_sym2str(mrb, id));
+  mrb_name_error(mrb, id, "no member '%n' in struct", id);
   return val;                   /* not reach */
 }
 
@@ -514,7 +498,7 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s)
     mrb_value sym = mrb_check_intern_str(mrb, idx);
 
     if (mrb_nil_p(sym)) {
-      mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx);
+      mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%v' in struct", idx);
     }
     idx = sym;
   }
@@ -526,13 +510,11 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s)
   if (i < 0) i = RSTRUCT_LEN(s) + i;
   if (i < 0) {
     mrb_raisef(mrb, E_INDEX_ERROR,
-               "offset %S too small for struct(size:%S)",
-               mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
+               "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s));
   }
   if (RSTRUCT_LEN(s) <= i) {
     mrb_raisef(mrb, E_INDEX_ERROR,
-               "offset %S too large for struct(size:%S)",
-               mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
+               "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s));
   }
   mrb_struct_modify(mrb, s);
   return RSTRUCT_PTR(s)[i] = val;
@@ -559,11 +541,10 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s)
 static mrb_value
 mrb_struct_equal(mrb_state *mrb, mrb_value s)
 {
-  mrb_value s2;
+  mrb_value s2 = mrb_get_arg1(mrb);
   mrb_value *ptr, *ptr2;
   mrb_int i, len;
 
-  mrb_get_args(mrb, "o", &s2);
   if (mrb_obj_equal(mrb, s, s2)) {
     return mrb_true_value();
   }
@@ -596,11 +577,10 @@ mrb_struct_equal(mrb_state *mrb, mrb_value s)
 static mrb_value
 mrb_struct_eql(mrb_state *mrb, mrb_value s)
 {
-  mrb_value s2;
+  mrb_value s2 = mrb_get_arg1(mrb);
   mrb_value *ptr, *ptr2;
   mrb_int i, len;
 
-  mrb_get_args(mrb, "o", &s2);
   if (mrb_obj_equal(mrb, s, s2)) {
     return mrb_true_value();
   }
index c298fef..9393073 100644 (file)
@@ -116,9 +116,10 @@ assert('struct dup') do
 end
 
 assert('struct inspect') do
-  c = Struct.new(:m1, :m2, :m3, :m4, :m5)
-  cc = c.new(1,2,3,4,5)
-  assert_equal "#<struct m1=1, m2=2, m3=3, m4=4, m5=5>", cc.inspect
+  c = Struct.new(:m1, :m2, :m3, :m4, :m5, :recur)
+  cc = c.new(1,2,3,4,5,nil)
+  cc.recur = cc
+  assert_equal "#<struct m1=1, m2=2, m3=3, m4=4, m5=5, recur=#<struct #{cc.class}:...>>", cc.inspect
 end
 
 assert('Struct#length, Struct#size') do
@@ -152,14 +153,14 @@ assert("Struct#dig") do
   assert_equal 1, a.dig(1, 0)
 end
 
-assert("Struct.new removes existing constant") do
-  skip "redefining Struct with same name cause warnings"
-  begin
-    assert_not_equal Struct.new("Test", :a), Struct.new("Test", :a, :b)
-  ensure
-    Struct.remove_const :Test
-  end
-end
+# TODO: suppress redefining Struct warning during test
+# assert("Struct.new removes existing constant") do
+  begin
+    assert_not_equal Struct.new("Test", :a), Struct.new("Test", :a, :b)
+  ensure
+    Struct.remove_const :Test
+  end
+end
 
 assert("Struct#initialize_copy requires struct to be the same type") do
   begin
@@ -181,6 +182,10 @@ assert("Struct.new does not allow array") do
   end
 end
 
+assert("Struct.new does not allow invalid class name") do
+  assert_raise(NameError) { Struct.new("Test-", :a) }
+end
+
 assert("Struct.new generates subclass of Struct") do
   begin
     original_struct = Struct
index ccb2971..ad922ad 100644 (file)
@@ -46,10 +46,10 @@ mrb_sym_length(mrb_state *mrb, mrb_value self)
   mrb_int len;
 #ifdef MRB_UTF8_STRING
   mrb_int byte_len;
-  const char *name = mrb_sym2name_len(mrb, mrb_symbol(self), &byte_len);
-  len = mrb_utf8_len(name, byte_len);
+  const char *name = mrb_sym_name_len(mrb, mrb_symbol(self), &byte_len);
+  len = mrb_utf8_strlen(name, byte_len);
 #else
-  mrb_sym2name_len(mrb, mrb_symbol(self), &len);
+  mrb_sym_name_len(mrb, mrb_symbol(self), &len);
 #endif
   return mrb_fixnum_value(len);
 }
index 61ecad2..db686e5 100644 (file)
@@ -14,7 +14,7 @@ end
   assert("Symbol##{n}") do
     assert_equal 5, :hello.__send__(n)
     assert_equal 4, :"aA\0b".__send__(n)
-    if "あ".size == 1  # enable MRB_UTF8_STRING?
+    if __ENCODING__ == "UTF-8"
       assert_equal 8, :"こんにちは世界!".__send__(n)
       assert_equal 4, :"aあ\0b".__send__(n)
     else
index fd180b1..a5f7239 100644 (file)
@@ -21,6 +21,7 @@
 extern const uint8_t mrbtest_assert_irep[];
 
 void mrbgemtest_init(mrb_state* mrb);
+void mrb_init_test_vformat(mrb_state* mrb);
 
 /* Print a short remark for the user */
 static void
@@ -51,9 +52,10 @@ t_print(mrb_state *mrb, mrb_value self)
 {
   mrb_value *argv;
   mrb_int argc;
+  mrb_int i;
 
   mrb_get_args(mrb, "*!", &argv, &argc);
-  for (mrb_int i = 0; i < argc; ++i) {
+  for (i = 0; i < argc; ++i) {
     mrb_value s = mrb_obj_as_string(mrb, argv[i]);
     fwrite(RSTRING_PTR(s), RSTRING_LEN(s), 1, stdout);
   }
@@ -62,6 +64,151 @@ t_print(mrb_state *mrb, mrb_value self)
   return mrb_nil_value();
 }
 
+#define UNESCAPE(p, endp) ((p) != (endp) && *(p) == '\\' ? (p)+1 : (p))
+#define CHAR_CMP(c1, c2) ((unsigned char)(c1) - (unsigned char)(c2))
+
+static const char *
+str_match_bracket(const char *p, const char *pat_end,
+                  const char *s, const char *str_end)
+{
+  mrb_bool ok = FALSE, negated = FALSE;
+
+  if (p == pat_end) return NULL;
+  if (*p == '!' || *p == '^') {
+    negated = TRUE;
+    ++p;
+  }
+
+  while (*p != ']') {
+    const char *t1 = p;
+    if ((t1 = UNESCAPE(t1, pat_end)) == pat_end) return NULL;
+    if ((p = t1 + 1) == pat_end) return NULL;
+    if (p[0] == '-' && p[1] != ']') {
+      const char *t2 = p + 1;
+      if ((t2 = UNESCAPE(t2, pat_end)) == pat_end) return NULL;
+      p = t2 + 1;
+      if (!ok && CHAR_CMP(*t1, *s) <= 0 && CHAR_CMP(*s, *t2) <= 0) ok = TRUE;
+    }
+    else {
+      if (!ok && CHAR_CMP(*t1, *s) == 0) ok = TRUE;
+    }
+  }
+
+  return ok == negated ? NULL : p + 1;
+}
+
+static mrb_bool
+str_match_no_brace_p(const char *pat, mrb_int pat_len,
+                     const char *str, mrb_int str_len)
+{
+  const char *p = pat, *s = str;
+  const char *pat_end = pat + pat_len, *str_end = str + str_len;
+  const char *p_tmp = NULL, *s_tmp = NULL;
+
+  for (;;) {
+    if (p == pat_end) return s == str_end;
+    switch (*p) {
+      case '*':
+        do { ++p; } while (p != pat_end && *p == '*');
+        if (UNESCAPE(p, pat_end) == pat_end) return TRUE;
+        if (s == str_end) return FALSE;
+        p_tmp = p;
+        s_tmp = s;
+        continue;
+      case '?':
+        if (s == str_end) return FALSE;
+        ++p;
+        ++s;
+        continue;
+      case '[': {
+        const char *t;
+        if (s == str_end) return FALSE;
+        if ((t = str_match_bracket(p+1, pat_end, s, str_end))) {
+          p = t;
+          ++s;
+          continue;
+        }
+        goto L_failed;
+      }
+    }
+
+    /* ordinary */
+    p = UNESCAPE(p, pat_end);
+    if (s == str_end) return p == pat_end;
+    if (p == pat_end) goto L_failed;
+    if (*p++ != *s++) goto L_failed;
+    continue;
+
+    L_failed:
+    if (p_tmp && s_tmp) {
+      /* try next '*' position */
+      p = p_tmp;
+      s = ++s_tmp;
+      continue;
+    }
+
+    return FALSE;
+  }
+}
+
+#define COPY_AND_INC(dst, src, len) \
+  do { memcpy(dst, src, len); dst += len; } while (0)
+
+static mrb_bool
+str_match_p(mrb_state *mrb,
+            const char *pat, mrb_int pat_len,
+            const char *str, mrb_int str_len)
+{
+  const char *p = pat, *pat_end = pat + pat_len;
+  const char *lbrace = NULL, *rbrace = NULL;
+  int nest = 0;
+  mrb_bool ret = FALSE;
+
+  for (; p != pat_end; ++p) {
+    if (*p == '{' && nest++ == 0) lbrace = p;
+    else if (*p == '}' && lbrace && --nest == 0) { rbrace = p; break; }
+    else if (*p == '\\' && ++p == pat_end) break;
+  }
+
+  if (lbrace && rbrace) {
+    /* expand brace */
+    char *ex_pat = (char *)mrb_malloc(mrb, pat_len-2);  /* expanded pattern */
+    char *ex_p = ex_pat;
+
+    COPY_AND_INC(ex_p, pat, lbrace-pat);
+    p = lbrace;
+    while (p < rbrace) {
+      char *orig_ex_p = ex_p;
+      const char *t = ++p;
+      for (nest = 0; p < rbrace && !(*p == ',' && nest == 0); ++p) {
+        if (*p == '{') ++nest;
+        else if (*p == '}') --nest;
+        else if (*p == '\\' && ++p == rbrace) break;
+      }
+      COPY_AND_INC(ex_p, t, p-t);
+      COPY_AND_INC(ex_p, rbrace+1, pat_end-rbrace-1);
+      if ((ret = str_match_p(mrb, ex_pat, ex_p-ex_pat, str, str_len))) break;
+      ex_p = orig_ex_p;
+    }
+    mrb_free(mrb, ex_pat);
+  }
+  else if (!lbrace && !rbrace) {
+    ret = str_match_no_brace_p(pat, pat_len, str, str_len);
+  }
+
+  return ret;
+}
+
+static mrb_value
+m_str_match_p(mrb_state *mrb, mrb_value self)
+{
+  const char *pat, *str;
+  mrb_int pat_len, str_len;
+
+  mrb_get_args(mrb, "ss", &pat, &pat_len, &str, &str_len);
+  return mrb_bool_value(str_match_p(mrb, pat, pat_len, str, str_len));
+}
+
 void
 mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose)
 {
@@ -69,6 +216,7 @@ mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose)
 
   krn = mrb->kernel_module;
   mrb_define_method(mrb, krn, "t_print", t_print, MRB_ARGS_ANY());
+  mrb_define_method(mrb, krn, "_str_match?", m_str_match_p, MRB_ARGS_REQ(2));
 
   mrbtest = mrb_define_module(mrb, "Mrbtest");
 
@@ -84,6 +232,8 @@ mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose)
 #endif
 #endif
 
+  mrb_init_test_vformat(mrb);
+
   if (verbose) {
     mrb_gv_set(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"), mrb_true_value());
   }
@@ -111,6 +261,7 @@ mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src)
   TEST_COUNT_PASS(ok_test);
   TEST_COUNT_PASS(ko_test);
   TEST_COUNT_PASS(kill_test);
+  TEST_COUNT_PASS(warning_test);
   TEST_COUNT_PASS(skip_test);
 
 #undef TEST_COUNT_PASS
index dcb7bb7..97189a6 100644 (file)
@@ -15,8 +15,9 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
   mrbtest_lib = libfile("#{build_dir}/mrbtest")
   mrbtest_objs = []
 
-  driver_obj = objfile("#{build_dir}/driver")
-  # driver = "#{spec.dir}/driver.c"
+  driver_objs = Dir.glob("#{dir}/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f|
+    objfile(f.relative_path_from(dir).to_s.pathmap("#{build_dir}/%X"))
+  end
 
   assert_c = "#{build_dir}/assert.c"
   assert_rb = "#{MRUBY_ROOT}/test/assert.rb"
@@ -25,6 +26,7 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
 
   file assert_lib => assert_c
   file assert_c => [assert_rb, build.mrbcfile] do |t|
+    mkdir_p File.dirname(t.name)
     open(t.name, 'w') do |f|
       mrbc.run f, assert_rb, 'mrbtest_assert_irep'
     end
@@ -39,7 +41,7 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
 
     file test_rbobj => g.test_rbireps
     file g.test_rbireps => [g.test_rbfiles, build.mrbcfile].flatten do |t|
-      FileUtils.mkdir_p File.dirname(t.name)
+      mkdir_p File.dirname(t.name)
       open(t.name, 'w') do |f|
         g.print_gem_test_header(f)
         test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir|
@@ -133,7 +135,7 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
   end
 
   unless build.build_mrbtest_lib_only?
-    file exec => [driver_obj, mlib, mrbtest_lib, build.libmruby_static] do |t|
+    file exec => [*driver_objs, mlib, mrbtest_lib, build.libmruby_static] do |t|
       gem_flags = build.gems.map { |g| g.linker.flags }
       gem_flags_before_libraries = build.gems.map { |g| g.linker.flags_before_libraries }
       gem_flags_after_libraries = build.gems.map { |g| g.linker.flags_after_libraries }
@@ -148,15 +150,10 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
   # of the test gem depending on a change to the gem
   # selection
   active_gems_path = "#{build_dir}/active_gems_path.lst"
-  active_gem_list = if File.exist? active_gems_path
-                      File.read active_gems_path
-                    else
-                      FileUtils.mkdir_p File.dirname(active_gems_path)
-                      nil
-                    end
+  active_gem_list = File.read active_gems_path if File.exist? active_gems_path
   current_gem_list = build.gems.map(&:name).join("\n")
   task active_gems_path do |_t|
-    FileUtils.mkdir_p File.dirname(active_gems_path)
+    mkdir_p File.dirname(active_gems_path)
     File.write active_gems_path, current_gem_list
   end
   file clib => active_gems_path if active_gem_list != current_gem_list
@@ -164,7 +161,7 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
   file mlib => clib
   file clib => [build.mrbcfile, __FILE__] do |_t|
     _pp "GEN", "*.rb", "#{clib.relative_path}"
-    FileUtils.mkdir_p File.dirname(clib)
+    mkdir_p File.dirname(clib)
     open(clib, 'w') do |f|
       f.puts %Q[/*]
       f.puts %Q[ * This file contains a list of all]
diff --git a/third-party/mruby/mrbgems/mruby-test/vformat.c b/third-party/mruby/mrbgems/mruby-test/vformat.c
new file mode 100644 (file)
index 0000000..e7ada02
--- /dev/null
@@ -0,0 +1,179 @@
+#include <string.h>
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/string.h>
+
+/* no argument */
+static mrb_value
+vf_s_format_0(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value fmt_str;
+  const char *fmt;
+
+  mrb_get_args(mrb, "S", &fmt_str);
+  fmt = RSTRING_CSTR(mrb, fmt_str);
+
+  return mrb_format(mrb, fmt);
+}
+
+/* c char */
+static mrb_value
+vf_s_format_c(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value fmt_str, arg_str;
+  const char *fmt;
+  char c;
+  
+  mrb_get_args(mrb, "SS", &fmt_str, &arg_str);
+  fmt = RSTRING_CSTR(mrb, fmt_str);
+  c = RSTRING_CSTR(mrb, arg_str)[0];
+
+  return mrb_format(mrb, fmt, c);
+}
+
+/* d int */
+static mrb_value
+vf_s_format_d(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value fmt_str;
+  const char *fmt;
+  mrb_int i;
+  int d;
+
+  mrb_get_args(mrb, "Si", &fmt_str, &i);
+  fmt = RSTRING_CSTR(mrb, fmt_str);
+  d = (int)i;
+
+  return mrb_format(mrb, fmt, d);
+}
+
+#ifndef MRB_WITHOUT_FLOAT
+/* f float */
+static mrb_value
+vf_s_format_f(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value fmt_str;
+  const char *fmt;
+  mrb_float f;
+
+  mrb_get_args(mrb, "Sf", &fmt_str, &f);
+  fmt = RSTRING_CSTR(mrb, fmt_str);
+
+  return mrb_format(mrb, fmt, f);
+}
+#endif
+
+/* i fixnum */
+static mrb_value
+vf_s_format_i(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value fmt_str;
+  const char *fmt;
+  mrb_int i;
+
+  mrb_get_args(mrb, "Si", &fmt_str, &i);
+  fmt = RSTRING_CSTR(mrb, fmt_str);
+
+  return mrb_format(mrb, fmt, i);
+}
+
+/* l char*, size_t */
+static mrb_value
+vf_s_format_l(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value fmt_str, arg_str;
+  const char *fmt;
+  const char *s;
+  mrb_int i;
+  size_t len;
+
+  mrb_get_args(mrb, "SSi", &fmt_str, &arg_str, &i);
+  fmt = RSTRING_CSTR(mrb, fmt_str);
+  s = RSTRING_PTR(arg_str);
+  len = (size_t)i;
+  if (len > (size_t)RSTRING_LEN(arg_str)) len = (size_t)RSTRING_LEN(arg_str);
+
+  return mrb_format(mrb, fmt, s, len);
+}
+
+/* n symbol */
+static mrb_value
+vf_s_format_n(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value fmt_str;
+  const char *fmt;
+  mrb_sym sym;
+
+  mrb_get_args(mrb, "Sn", &fmt_str, &sym);
+  fmt = RSTRING_CSTR(mrb, fmt_str);
+
+  return mrb_format(mrb, fmt, sym);
+}
+
+/* s char* */
+static mrb_value
+vf_s_format_s(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value fmt_str, arg_str;
+  const char *fmt;
+  const char *s;
+
+  mrb_get_args(mrb, "SS", &fmt_str, &arg_str);
+  fmt = RSTRING_CSTR(mrb, fmt_str);
+  s = RSTRING_CSTR(mrb, arg_str);
+
+  return mrb_format(mrb, fmt, s);
+}
+
+/* C RClass */
+static mrb_value
+vf_s_format_C(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value fmt_str, arg_cls;
+  const char *fmt;
+  struct RClass *c;
+
+  mrb_get_args(mrb, "SC", &fmt_str, &arg_cls);
+  fmt = RSTRING_CSTR(mrb, fmt_str);
+  c = mrb_class_ptr(arg_cls);
+
+  return mrb_format(mrb, fmt, c);
+}
+
+/* v value */
+static mrb_value
+vf_s_format_v(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value fmt_str, arg_v;
+  const char *fmt;
+
+  mrb_get_args(mrb, "So", &fmt_str, &arg_v);
+  fmt = RSTRING_CSTR(mrb, fmt_str);
+
+  return mrb_format(mrb, fmt, arg_v);
+}
+
+void
+mrb_init_test_vformat(mrb_state *mrb)
+{
+  struct RClass *vf;
+
+  vf = mrb_define_module(mrb, "TestVFormat");
+  mrb_define_class_method(mrb, vf, "z", vf_s_format_0, MRB_ARGS_REQ(1));
+
+#define VF_DEFINE_FORMAT_METHOD(t) VF_DEFINE_FORMAT_METHOD_n(t,2)
+#define VF_DEFINE_FORMAT_METHOD_n(t,n) mrb_define_class_method(mrb, vf, #t, vf_s_format_##t, MRB_ARGS_REQ(n));
+  
+  VF_DEFINE_FORMAT_METHOD(c);
+  VF_DEFINE_FORMAT_METHOD(d);
+#ifndef MRB_WITHOUT_FLOAT
+  VF_DEFINE_FORMAT_METHOD(f);
+#endif
+  VF_DEFINE_FORMAT_METHOD(i);
+  VF_DEFINE_FORMAT_METHOD_n(l,3);
+  VF_DEFINE_FORMAT_METHOD(n);
+  VF_DEFINE_FORMAT_METHOD(s);
+  VF_DEFINE_FORMAT_METHOD(C);
+  VF_DEFINE_FORMAT_METHOD(v);
+}
index d71f4cc..1adcfd4 100644 (file)
@@ -8,6 +8,7 @@
 #define MRUBY_TIME_H
 
 #include "mruby/common.h"
+#include <time.h>
 
 MRB_BEGIN_DECL
 
@@ -18,7 +19,7 @@ typedef enum mrb_timezone {
   MRB_TIMEZONE_LAST   = 3
 } mrb_timezone;
 
-MRB_API mrb_value mrb_time_at(mrb_state *mrb, double sec, double usec, mrb_timezone timezone);
+MRB_API mrb_value mrb_time_at(mrb_state *mrb, time_t sec, time_t usec, mrb_timezone timezone);
 
 MRB_END_DECL
 
index 7f6c300..5fa7008 100644 (file)
@@ -4,20 +4,25 @@
 ** See Copyright Notice in mruby.h
 */
 
+#ifndef MRB_WITHOUT_FLOAT
 #include <math.h>
-#include <time.h>
+#endif
+
 #include <mruby.h>
 #include <mruby/class.h>
 #include <mruby/data.h>
+#include <mruby/numeric.h>
 #include <mruby/time.h>
+#include <mruby/string.h>
 
-#ifndef MRB_DISABLE_STDIO
-#include <stdio.h>
-#else
+#ifdef MRB_DISABLE_STDIO
 #include <string.h>
 #endif
 
+#include <stdlib.h>
+
 #define NDIV(x,y) (-(-((x)+1)/(y))-1)
+#define TO_S_FMT "%Y-%m-%d %H:%M:%S "
 
 #if defined(_MSC_VER) && _MSC_VER < 1800
 double round(double x) {
@@ -25,8 +30,10 @@ double round(double x) {
 }
 #endif
 
-#if !defined(__MINGW64__) && defined(_WIN32)
-# define llround(x) round(x)
+#ifndef MRB_WITHOUT_FLOAT
+# if !defined(__MINGW64__) && defined(_WIN32)
+#  define llround(x) round(x)
+# endif
 #endif
 
 #if defined(__MINGW64__) || defined(__MINGW32__)
@@ -68,11 +75,6 @@ double round(double x) {
 /* define following macro to use probably faster timegm() on the platform */
 /* #define USE_SYSTEM_TIMEGM */
 
-/* time_t */
-/* If your platform supports time_t as uint (e.g. uint32_t, uint64_t), */
-/* uncomment following macro. */
-/* #define MRB_TIME_T_UINT */
-
 /** end of Time class configuration */
 
 #ifndef NO_GETTIMEOFDAY
@@ -197,6 +199,84 @@ struct mrb_time {
 
 static const struct mrb_data_type mrb_time_type = { "Time", mrb_free };
 
+#ifndef MRB_WITHOUT_FLOAT
+void mrb_check_num_exact(mrb_state *mrb, mrb_float num);
+typedef mrb_float mrb_sec;
+#define mrb_sec_value(mrb, sec) mrb_float_value(mrb, sec)
+#else
+typedef mrb_int mrb_sec;
+#define mrb_sec_value(mrb, sec) mrb_fixnum_value(sec)
+#endif
+
+#define MRB_TIME_T_UINT (~(time_t)0 > 0)
+#define MRB_TIME_MIN (                                                      \
+  MRB_TIME_T_UINT ? 0 :                                                     \
+                    (sizeof(time_t) <= 4 ? INT32_MIN : INT64_MIN)           \
+)
+#define MRB_TIME_MAX (                                                      \
+  MRB_TIME_T_UINT ? (sizeof(time_t) <= 4 ? UINT32_MAX : UINT64_MAX) :       \
+                    (sizeof(time_t) <= 4 ? INT32_MAX : INT64_MAX)           \
+)
+
+static mrb_bool
+fixable_time_t_p(time_t v)
+{
+  if (MRB_INT_MIN <= MRB_TIME_MIN && MRB_TIME_MAX <= MRB_INT_MAX) return TRUE;
+  return FIXABLE(v);
+}
+
+static time_t
+mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec)
+{
+  time_t t;
+
+  switch (mrb_type(obj)) {
+#ifndef MRB_WITHOUT_FLOAT
+    case MRB_TT_FLOAT:
+      {
+        mrb_float f = mrb_float(obj);
+
+        mrb_check_num_exact(mrb, f);
+        if (f >= ((mrb_float)MRB_TIME_MAX-1.0) || f < ((mrb_float)MRB_TIME_MIN+1.0)) {
+          goto out_of_range;
+        }
+
+        if (usec) {
+          t = (time_t)f;
+          *usec = (time_t)llround((f - t) * 1.0e+6);
+        }
+        else {
+          t = (time_t)llround(f);
+        }
+      }
+      break;
+#endif /* MRB_WITHOUT_FLOAT */
+    default:
+    case MRB_TT_FIXNUM:
+      {
+        mrb_int i = mrb_int(mrb, obj);
+
+        if ((MRB_INT_MAX > MRB_TIME_MAX && i > 0 && i > (mrb_int)MRB_TIME_MAX) ||
+            (MRB_TIME_MIN > MRB_INT_MIN && MRB_TIME_MIN > i)) {
+          goto out_of_range;
+        }
+
+        t = (time_t)i;
+        if (usec) { *usec = 0; }
+      }
+      break;
+  }
+
+  return t;
+
+out_of_range:
+  mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", obj);
+
+  /* not reached */
+  if (usec) { *usec = 0; }
+  return 0;
+}
+
 /** Updates the datetime of a mrb_time based on it's timezone and
     seconds setting. Returns self on success, NULL of failure.
     if `dealloc` is set `true`, it frees `self` on error. */
@@ -204,18 +284,19 @@ static struct mrb_time*
 time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc)
 {
   struct tm *aid;
+  time_t t = self->sec;
 
   if (self->timezone == MRB_TIMEZONE_UTC) {
-    aid = gmtime_r(&self->sec, &self->datetime);
+    aid = gmtime_r(&t, &self->datetime);
   }
   else {
-    aid = localtime_r(&self->sec, &self->datetime);
+    aid = localtime_r(&t, &self->datetime);
   }
   if (!aid) {
-    mrb_float sec = (mrb_float)self->sec;
+    mrb_sec sec = (mrb_sec)t;
 
-    mrb_free(mrb, self);
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec));
+    if (dealloc) mrb_free(mrb, self);
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", mrb_sec_value(mrb, sec));
     /* not reached */
     return NULL;
   }
@@ -232,40 +313,15 @@ mrb_time_wrap(mrb_state *mrb, struct RClass *tc, struct mrb_time *tm)
   return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &mrb_time_type, tm));
 }
 
-void mrb_check_num_exact(mrb_state *mrb, mrb_float num);
-
 /* Allocates a mrb_time object and initializes it. */
 static struct mrb_time*
-time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone)
+time_alloc_time(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone timezone)
 {
   struct mrb_time *tm;
-  time_t tsec = 0;
 
-  mrb_check_num_exact(mrb, (mrb_float)sec);
-  mrb_check_num_exact(mrb, (mrb_float)usec);
-#ifndef MRB_TIME_T_UINT
-  if (sizeof(time_t) == 4 && (sec > (double)INT32_MAX || (double)INT32_MIN > sec)) {
-    goto out_of_range;
-  }
-  if (sizeof(time_t) == 8 && (sec > (double)INT64_MAX || (double)INT64_MIN > sec)) {
-    goto out_of_range;
-  }
-#else
-  if (sizeof(time_t) == 4 && (sec > (double)UINT32_MAX || (double)0 > sec)) {
-    goto out_of_range;
-  }
-  if (sizeof(time_t) == 8 && (sec > (double)UINT64_MAX || (double)0 > sec)) {
-    goto out_of_range;
-  }
-#endif
-  tsec  = (time_t)sec;
-  if ((sec > 0 && tsec < 0) || (sec < 0 && (double)tsec > sec)) {
-  out_of_range:
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec));
-  }
   tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time));
-  tm->sec  = tsec;
-  tm->usec = (time_t)llround((sec - tm->sec) * 1.0e6 + usec);
+  tm->sec  = sec;
+  tm->usec = usec;
   if (tm->usec < 0) {
     long sec2 = (long)NDIV(tm->usec,1000000); /* negative div */
     tm->usec -= sec2 * 1000000;
@@ -282,8 +338,25 @@ time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone)
   return tm;
 }
 
+static struct mrb_time*
+time_alloc(mrb_state *mrb, mrb_value sec, mrb_value usec, enum mrb_timezone timezone)
+{
+  time_t tsec, tusec;
+
+  tsec = mrb_to_time_t(mrb, sec, &tusec);
+  tusec += mrb_to_time_t(mrb, usec, NULL);
+
+  return time_alloc_time(mrb, tsec, tusec, timezone);
+}
+
+static mrb_value
+mrb_time_make_time(mrb_state *mrb, struct RClass *c, time_t sec, time_t usec, enum mrb_timezone timezone)
+{
+  return mrb_time_wrap(mrb, c, time_alloc_time(mrb, sec, usec, timezone));
+}
+
 static mrb_value
-mrb_time_make(mrb_state *mrb, struct RClass *c, double sec, double usec, enum mrb_timezone timezone)
+mrb_time_make(mrb_state *mrb, struct RClass *c, mrb_value sec, mrb_value usec, enum mrb_timezone timezone)
 {
   return mrb_time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone));
 }
@@ -291,43 +364,46 @@ mrb_time_make(mrb_state *mrb, struct RClass *c, double sec, double usec, enum mr
 static struct mrb_time*
 current_mrb_time(mrb_state *mrb)
 {
+  struct mrb_time tmzero = {0};
   struct mrb_time *tm;
+  time_t sec, usec;
 
-  tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
 #if defined(TIME_UTC) && !defined(__ANDROID__)
   {
     struct timespec ts;
     if (timespec_get(&ts, TIME_UTC) == 0) {
-      mrb_free(mrb, tm);
       mrb_raise(mrb, E_RUNTIME_ERROR, "timespec_get() failed for unknown reasons");
     }
-    tm->sec = ts.tv_sec;
-    tm->usec = ts.tv_nsec / 1000;
+    sec = ts.tv_sec;
+    usec = ts.tv_nsec / 1000;
   }
 #elif defined(NO_GETTIMEOFDAY)
   {
     static time_t last_sec = 0, last_usec = 0;
 
-    tm->sec  = time(NULL);
-    if (tm->sec != last_sec) {
-      last_sec = tm->sec;
+    sec = time(NULL);
+    if (sec != last_sec) {
+      last_sec = sec;
       last_usec = 0;
     }
     else {
       /* add 1 usec to differentiate two times */
       last_usec += 1;
     }
-    tm->usec = last_usec;
+    usec = last_usec;
   }
 #else
   {
     struct timeval tv;
 
     gettimeofday(&tv, NULL);
-    tm->sec = tv.tv_sec;
-    tm->usec = tv.tv_usec;
+    sec = tv.tv_sec;
+    usec = tv.tv_usec;
   }
 #endif
+  tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
+  *tm = tmzero;
+  tm->sec = sec; tm->usec = usec;
   tm->timezone = MRB_TIMEZONE_LOCAL;
   time_update_datetime(mrb, tm, TRUE);
 
@@ -342,9 +418,9 @@ mrb_time_now(mrb_state *mrb, mrb_value self)
 }
 
 MRB_API mrb_value
-mrb_time_at(mrb_state *mrb, double sec, double usec, enum mrb_timezone zone)
+mrb_time_at(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone zone)
 {
-  return mrb_time_make(mrb, mrb_class_get(mrb, "Time"), sec, usec, zone);
+  return mrb_time_make_time(mrb, mrb_class_get(mrb, "Time"), sec, usec, zone);
 }
 
 /* 15.2.19.6.1 */
@@ -352,10 +428,12 @@ mrb_time_at(mrb_state *mrb, double sec, double usec, enum mrb_timezone zone)
 static mrb_value
 mrb_time_at_m(mrb_state *mrb, mrb_value self)
 {
-  mrb_float f, f2 = 0;
+  mrb_value sec;
+  mrb_value usec = mrb_fixnum_value(0);
+
+  mrb_get_args(mrb, "o|o", &sec, &usec);
 
-  mrb_get_args(mrb, "f|f", &f, &f2);
-  return mrb_time_make(mrb, mrb_class_ptr(self), f, f2, MRB_TIMEZONE_LOCAL);
+  return mrb_time_make(mrb, mrb_class_ptr(self), sec, usec, MRB_TIMEZONE_LOCAL);
 }
 
 static struct mrb_time*
@@ -392,7 +470,7 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday,
     mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time.");
   }
 
-  return time_alloc(mrb, (double)nowsecs, (double)ausec, timezone);
+  return time_alloc_time(mrb, nowsecs, ausec, timezone);
 }
 
 /* 15.2.19.6.2 */
@@ -437,11 +515,10 @@ time_get_ptr(mrb_state *mrb, mrb_value time)
 static mrb_value
 mrb_time_eq(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other;
+  mrb_value other = mrb_get_arg1(mrb);
   struct mrb_time *tm1, *tm2;
   mrb_bool eq_p;
 
-  mrb_get_args(mrb, "o", &other);
   tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);
   tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time);
   eq_p = tm1 && tm2 && tm1->sec == tm2->sec && tm1->usec == tm2->usec;
@@ -452,10 +529,9 @@ mrb_time_eq(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_time_cmp(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other;
+  mrb_value other = mrb_get_arg1(mrb);
   struct mrb_time *tm1, *tm2;
 
-  mrb_get_args(mrb, "o", &other);
   tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);
   tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time);
   if (!tm1 || !tm2) return mrb_nil_value();
@@ -478,32 +554,40 @@ mrb_time_cmp(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_time_plus(mrb_state *mrb, mrb_value self)
 {
-  mrb_float f;
+  mrb_value o = mrb_get_arg1(mrb);
   struct mrb_time *tm;
+  time_t sec, usec;
 
-  mrb_get_args(mrb, "f", &f);
   tm = time_get_ptr(mrb, self);
-  return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec+f, (double)tm->usec, tm->timezone);
+  sec = mrb_to_time_t(mrb, o, &usec);
+  return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), tm->sec+sec, tm->usec+usec, tm->timezone);
 }
 
 static mrb_value
 mrb_time_minus(mrb_state *mrb, mrb_value self)
 {
-  mrb_float f;
-  mrb_value other;
+  mrb_value other = mrb_get_arg1(mrb);
   struct mrb_time *tm, *tm2;
 
-  mrb_get_args(mrb, "o", &other);
   tm = time_get_ptr(mrb, self);
   tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time);
   if (tm2) {
-    f = (mrb_float)(tm->sec - tm2->sec)
-      + (mrb_float)(tm->usec - tm2->usec) / 1.0e6;
+#ifndef MRB_WITHOUT_FLOAT
+    mrb_float f;
+    f = (mrb_sec)(tm->sec - tm2->sec)
+      + (mrb_sec)(tm->usec - tm2->usec) / 1.0e6;
     return mrb_float_value(mrb, f);
+#else
+    mrb_int f;
+    f = tm->sec - tm2->sec;
+    if (tm->usec < tm2->usec) f--;
+    return mrb_fixnum_value(f);
+#endif
   }
   else {
-    mrb_get_args(mrb, "f", &f);
-    return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec-f, (double)tm->usec, tm->timezone);
+    time_t sec, usec;
+    sec = mrb_to_time_t(mrb, other, &usec);
+    return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), tm->sec-sec, tm->usec-usec, tm->timezone);
   }
 }
 
@@ -576,10 +660,9 @@ mrb_time_asctime(mrb_state *mrb, mrb_value self)
 #else
   char buf[256];
 
-  len = snprintf(buf, sizeof(buf), "%s %s %02d %02d:%02d:%02d %s%d",
+  len = snprintf(buf, sizeof(buf), "%s %s %2d %02d:%02d:%02d %.4d",
     wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday,
     d->tm_hour, d->tm_min, d->tm_sec,
-    tm->timezone == MRB_TIMEZONE_UTC ? "UTC " : "",
     d->tm_year + 1900);
 #endif
   return mrb_str_new(mrb, buf, len);
@@ -683,10 +766,9 @@ mrb_time_initialize(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy)
 {
-  mrb_value src;
+  mrb_value src = mrb_get_arg1(mrb);
   struct mrb_time *t1, *t2;
 
-  mrb_get_args(mrb, "o", &src);
   if (mrb_obj_equal(mrb, copy, src)) return copy;
   if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
     mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
@@ -761,7 +843,7 @@ mrb_time_sec(mrb_state *mrb, mrb_value self)
   return mrb_fixnum_value(tm->datetime.tm_sec);
 }
 
-
+#ifndef MRB_WITHOUT_FLOAT
 /* 15.2.19.7.24 */
 /* Returns a Float with the time since the epoch in seconds. */
 static mrb_value
@@ -772,32 +854,37 @@ mrb_time_to_f(mrb_state *mrb, mrb_value self)
   tm = time_get_ptr(mrb, self);
   return mrb_float_value(mrb, (mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6);
 }
+#endif
 
 /* 15.2.19.7.25 */
-/* Returns a Fixnum with the time since the epoch in seconds. */
+/* Returns an Integer with the time since the epoch in seconds. */
 static mrb_value
 mrb_time_to_i(mrb_state *mrb, mrb_value self)
 {
   struct mrb_time *tm;
 
   tm = time_get_ptr(mrb, self);
-  if (tm->sec > MRB_INT_MAX || tm->sec < MRB_INT_MIN) {
+#ifndef MRB_WITHOUT_FLOAT
+  if (!fixable_time_t_p(tm->sec)) {
     return mrb_float_value(mrb, (mrb_float)tm->sec);
   }
+#endif
   return mrb_fixnum_value((mrb_int)tm->sec);
 }
 
 /* 15.2.19.7.26 */
-/* Returns a Float with the time since the epoch in microseconds. */
+/* Returns an Integer with the time since the epoch in microseconds. */
 static mrb_value
 mrb_time_usec(mrb_state *mrb, mrb_value self)
 {
   struct mrb_time *tm;
 
   tm = time_get_ptr(mrb, self);
-  if (tm->usec > MRB_INT_MAX || tm->usec < MRB_INT_MIN) {
+#ifndef MRB_WITHOUT_FLOAT
+  if (!fixable_time_t_p(tm->usec)) {
     return mrb_float_value(mrb, (mrb_float)tm->usec);
   }
+#endif
   return mrb_fixnum_value((mrb_int)tm->usec);
 }
 
@@ -825,6 +912,48 @@ mrb_time_utc_p(mrb_state *mrb, mrb_value self)
   return mrb_bool_value(tm->timezone == MRB_TIMEZONE_UTC);
 }
 
+static size_t
+time_to_s_utc(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t buf_len)
+{
+  return strftime(buf, buf_len, TO_S_FMT "UTC", &tm->datetime);
+}
+
+static size_t
+time_to_s_local(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t buf_len)
+{
+#if defined(_MSC_VER) && _MSC_VER < 1900 || defined(__MINGW64__) || defined(__MINGW32__)
+  struct tm datetime = {0};
+  time_t utc_sec = timegm(&tm->datetime);
+  size_t len;
+  int offset;
+
+  if (utc_sec == (time_t)-1) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time.");
+  }
+  offset = abs((int)(utc_sec - tm->sec) / 60);
+  datetime.tm_year = 100;
+  datetime.tm_hour = offset / 60;
+  datetime.tm_min = offset % 60;
+  len = strftime(buf, buf_len, TO_S_FMT, &tm->datetime);
+  buf[len++] = utc_sec < tm->sec ? '-' : '+';
+
+  return len + strftime(buf + len, buf_len - len, "%H%M", &datetime);
+#else
+  return strftime(buf, buf_len, TO_S_FMT "%z", &tm->datetime);
+#endif
+}
+
+static mrb_value
+mrb_time_to_s(mrb_state *mrb, mrb_value self)
+{
+  char buf[64];
+  struct mrb_time *tm = time_get_ptr(mrb, self);
+  mrb_bool utc = tm->timezone == MRB_TIMEZONE_UTC;
+  size_t len = (utc ? time_to_s_utc : time_to_s_local)(mrb, tm, buf, sizeof(buf));
+  mrb_value str = mrb_str_new(mrb, buf, len);
+  RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+  return str;
+}
 
 void
 mrb_mruby_time_gem_init(mrb_state* mrb)
@@ -845,8 +974,8 @@ mrb_mruby_time_gem_init(mrb_state* mrb)
   mrb_define_method(mrb, tc, "<=>"    , mrb_time_cmp    , MRB_ARGS_REQ(1)); /* 15.2.19.7.1 */
   mrb_define_method(mrb, tc, "+"      , mrb_time_plus   , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */
   mrb_define_method(mrb, tc, "-"      , mrb_time_minus  , MRB_ARGS_REQ(1)); /* 15.2.19.7.3 */
-  mrb_define_method(mrb, tc, "to_s"   , mrb_time_asctime, MRB_ARGS_NONE());
-  mrb_define_method(mrb, tc, "inspect", mrb_time_asctime, MRB_ARGS_NONE());
+  mrb_define_method(mrb, tc, "to_s"   , mrb_time_to_s   , MRB_ARGS_NONE());
+  mrb_define_method(mrb, tc, "inspect", mrb_time_to_s   , MRB_ARGS_NONE());
   mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.4 */
   mrb_define_method(mrb, tc, "ctime"  , mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.5 */
   mrb_define_method(mrb, tc, "day"    , mrb_time_day    , MRB_ARGS_NONE()); /* 15.2.19.7.6 */
@@ -866,7 +995,9 @@ mrb_mruby_time_gem_init(mrb_state* mrb)
 
   mrb_define_method(mrb, tc, "sec" , mrb_time_sec, MRB_ARGS_NONE());        /* 15.2.19.7.23 */
   mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, MRB_ARGS_NONE());       /* 15.2.19.7.25 */
+#ifndef MRB_WITHOUT_FLOAT
   mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, MRB_ARGS_NONE());       /* 15.2.19.7.24 */
+#endif
   mrb_define_method(mrb, tc, "usec", mrb_time_usec, MRB_ARGS_NONE());       /* 15.2.19.7.26 */
   mrb_define_method(mrb, tc, "utc" , mrb_time_utc, MRB_ARGS_NONE());        /* 15.2.19.7.27 */
   mrb_define_method(mrb, tc, "utc?", mrb_time_utc_p,MRB_ARGS_NONE());       /* 15.2.19.7.28 */
index 54c446c..be1de7b 100644 (file)
@@ -2,11 +2,11 @@
 # Time ISO Test
 
 assert('Time.new', '15.2.3.3.3') do
-  Time.new.class == Time
+  assert_equal(Time, Time.new.class)
 end
 
 assert('Time', '15.2.19') do
-  Time.class == Class
+  assert_equal(Class, Time.class)
 end
 
 assert('Time.at', '15.2.19.6.1') do
@@ -21,30 +21,58 @@ assert('Time.at', '15.2.19.6.1') do
 end
 
 assert('Time.gm', '15.2.19.6.2') do
-  Time.gm(2012, 12, 23)
+  t = Time.gm(2012, 9, 23)
+  assert_operator(2012, :eql?, t.year)
+  assert_operator(   9, :eql?, t.month)
+  assert_operator(  23, :eql?, t.day)
+  assert_operator(   0, :eql?, t.hour)
+  assert_operator(   0, :eql?, t.min)
+  assert_operator(   0, :eql?, t.sec)
+  assert_operator(   0, :eql?, t.usec)
 end
 
 assert('Time.local', '15.2.19.6.3') do
-  Time.local(2012, 12, 23)
+  t = Time.local(2014, 12, 27, 18)
+  assert_operator(2014, :eql?, t.year)
+  assert_operator(  12, :eql?, t.month)
+  assert_operator(  27, :eql?, t.day)
+  assert_operator(  18, :eql?, t.hour)
+  assert_operator(   0, :eql?, t.min)
+  assert_operator(   0, :eql?, t.sec)
+  assert_operator(   0, :eql?, t.usec)
 end
 
 assert('Time.mktime', '15.2.19.6.4') do
-  Time.mktime(2012, 12, 23)
+  t = Time.mktime(2013, 10, 4, 6, 15, 58, 3485)
+  assert_operator(2013, :eql?, t.year)
+  assert_operator(  10, :eql?, t.month)
+  assert_operator(   4, :eql?, t.day)
+  assert_operator(   6, :eql?, t.hour)
+  assert_operator(  15, :eql?, t.min)
+  assert_operator(  58, :eql?, t.sec)
+  assert_operator(3485, :eql?, t.usec)
 end
 
 assert('Time.now', '15.2.19.6.5') do
-  Time.now.class == Time
+  assert_equal(Time, Time.now.class)
 end
 
 assert('Time.utc', '15.2.19.6.6') do
-  Time.utc(2012, 12, 23)
+  t = Time.utc(2034)
+  assert_operator(2034, :eql?, t.year)
+  assert_operator(   1, :eql?, t.month)
+  assert_operator(   1, :eql?, t.day)
+  assert_operator(   0, :eql?, t.hour)
+  assert_operator(   0, :eql?, t.min)
+  assert_operator(   0, :eql?, t.sec)
+  assert_operator(   0, :eql?, t.usec)
 end
 
 assert('Time#+', '15.2.19.7.1') do
   t1 = Time.at(1300000000.0)
   t2 = t1.+(60)
 
-  assert_equal(t2.utc.asctime, "Sun Mar 13 07:07:40 UTC 2011")
+  assert_equal("Sun Mar 13 07:07:40 2011", t2.utc.asctime)
 
   assert_raise(FloatDomainError) { Time.at(0) + Float::NAN }
   assert_raise(FloatDomainError) { Time.at(0) + Float::INFINITY }
@@ -55,7 +83,7 @@ assert('Time#-', '15.2.19.7.2') do
   t1 = Time.at(1300000000.0)
   t2 = t1.-(60)
 
-  assert_equal(t2.utc.asctime, "Sun Mar 13 07:05:40 UTC 2011")
+  assert_equal("Sun Mar 13 07:05:40 2011", t2.utc.asctime)
 
   assert_raise(FloatDomainError) { Time.at(0) - Float::NAN }
   assert_raise(FloatDomainError) { Time.at(0) - Float::INFINITY }
@@ -67,30 +95,30 @@ assert('Time#<=>', '15.2.19.7.3') do
   t2 = Time.at(1400000000.0)
   t3 = Time.at(1500000000.0)
 
-  t2.<=>(t1) == 1 and
-    t2.<=>(t2) == 0 and
-    t2.<=>(t3) == -1 and
-    t2.<=>(nil) == nil
+  assert_equal(1, t2 <=> t1)
+  assert_equal(0, t2 <=> t2)
+  assert_equal(-1, t2 <=> t3)
+  assert_nil(t2 <=> nil)
 end
 
 assert('Time#asctime', '15.2.19.7.4') do
-  Time.at(1300000000.0).utc.asctime == "Sun Mar 13 07:06:40 UTC 2011"
+  assert_equal("Thu Mar  4 05:06:07 1982", Time.gm(1982,3,4,5,6,7).asctime)
 end
 
 assert('Time#ctime', '15.2.19.7.5') do
-  Time.at(1300000000.0).utc.ctime == "Sun Mar 13 07:06:40 UTC 2011"
+  assert_equal("Thu Oct 24 15:26:47 2013", Time.gm(2013,10,24,15,26,47).ctime)
 end
 
 assert('Time#day', '15.2.19.7.6') do
-  Time.gm(2012, 12, 23).day == 23
+  assert_equal(23, Time.gm(2012, 12, 23).day)
 end
 
 assert('Time#dst?', '15.2.19.7.7') do
-  not Time.gm(2012, 12, 23).utc.dst?
+  assert_not_predicate(Time.gm(2012, 12, 23).utc, :dst?)
 end
 
 assert('Time#getgm', '15.2.19.7.8') do
-  Time.at(1300000000.0).getgm.asctime == "Sun Mar 13 07:06:40 UTC 2011"
+  assert_equal("Sun Mar 13 07:06:40 2011", Time.at(1300000000.0).getgm.asctime)
 end
 
 assert('Time#getlocal', '15.2.19.7.9') do
@@ -98,114 +126,121 @@ assert('Time#getlocal', '15.2.19.7.9') do
   t2 = Time.at(1300000000.0)
   t3 = t1.getlocal
 
-  t1 == t3 and t3 == t2.getlocal
+  assert_equal(t1, t3)
+  assert_equal(t3, t2.getlocal)
 end
 
 assert('Time#getutc', '15.2.19.7.10') do
-  Time.at(1300000000.0).getutc.asctime == "Sun Mar 13 07:06:40 UTC 2011"
+  assert_equal("Sun Mar 13 07:06:40 2011", Time.at(1300000000.0).getutc.asctime)
 end
 
 assert('Time#gmt?', '15.2.19.7.11') do
-  Time.at(1300000000.0).utc.gmt?
+  assert_predicate(Time.at(1300000000.0).utc, :gmt?)
 end
 
 # ATM not implemented
 # assert('Time#gmt_offset', '15.2.19.7.12') do
 
 assert('Time#gmtime', '15.2.19.7.13') do
-  Time.at(1300000000.0).gmtime
+  t = Time.now
+  assert_predicate(t.gmtime, :gmt?)
+  assert_predicate(t, :gmt?)
 end
 
 # ATM not implemented
 # assert('Time#gmtoff', '15.2.19.7.14') do
 
 assert('Time#hour', '15.2.19.7.15') do
-  Time.gm(2012, 12, 23, 7, 6).hour == 7
+  assert_equal(7, Time.gm(2012, 12, 23, 7, 6).hour)
 end
 
 # ATM doesn't really work
 # assert('Time#initialize', '15.2.19.7.16') do
 
 assert('Time#initialize_copy', '15.2.19.7.17') do
-  time_tmp_2 = Time.at(7.0e6)
-  time_tmp_2.clone == time_tmp_2
+  t = Time.at(7.0e6)
+  assert_equal(t, t.clone)
 end
 
 assert('Time#localtime', '15.2.19.7.18') do
-  t1 = Time.at(1300000000.0)
-  t2 = Time.at(1300000000.0)
+  t1 = Time.utc(2014, 5 ,6)
+  t2 = Time.utc(2014, 5 ,6)
+  t3 = t2.getlocal
 
-  t1.localtime
-  t1 == t2.getlocal
+  assert_equal(t3, t1.localtime)
+  assert_equal(t3, t1)
 end
 
 assert('Time#mday', '15.2.19.7.19') do
-  Time.gm(2012, 12, 23).mday == 23
+  assert_equal(23, Time.gm(2012, 12, 23).mday)
 end
 
 assert('Time#min', '15.2.19.7.20') do
-  Time.gm(2012, 12, 23, 7, 6).min == 6
+  assert_equal(6, Time.gm(2012, 12, 23, 7, 6).min)
 end
 
 assert('Time#mon', '15.2.19.7.21') do
-  Time.gm(2012, 12, 23).mon == 12
+  assert_equal(12, Time.gm(2012, 12, 23).mon)
 end
 
 assert('Time#month', '15.2.19.7.22') do
-  Time.gm(2012, 12, 23).month == 12
+  assert_equal(12, Time.gm(2012, 12, 23).month)
 end
 
 assert('Times#sec', '15.2.19.7.23') do
-  Time.gm(2012, 12, 23, 7, 6, 40).sec == 40
+  assert_equal(40, Time.gm(2012, 12, 23, 7, 6, 40).sec)
 end
 
 assert('Time#to_f', '15.2.19.7.24') do
-  Time.at(1300000000.0).to_f == 1300000000.0
+  assert_operator(2.0, :eql?, Time.at(2).to_f)
 end
 
 assert('Time#to_i', '15.2.19.7.25') do
-  Time.at(1300000000.0).to_i == 1300000000
+  assert_operator(2, :eql?, Time.at(2.0).to_i)
 end
 
 assert('Time#usec', '15.2.19.7.26') do
-  Time.at(1300000000.0).usec == 0
+  assert_equal(0, Time.at(1300000000.0).usec)
 end
 
 assert('Time#utc', '15.2.19.7.27') do
-  Time.at(1300000000.0).utc
+  t = Time.now
+  assert_predicate(t.utc, :gmt?)
+  assert_predicate(t, :gmt?)
 end
 
 assert('Time#utc?', '15.2.19.7.28') do
-  Time.at(1300000000.0).utc.utc?
+  assert_predicate(Time.at(1300000000.0).utc, :utc?)
 end
 
 # ATM not implemented
 # assert('Time#utc_offset', '15.2.19.7.29') do
 
 assert('Time#wday', '15.2.19.7.30') do
-  Time.gm(2012, 12, 23).wday == 0
+  assert_equal(0, Time.gm(2012, 12, 23).wday)
 end
 
 assert('Time#yday', '15.2.19.7.31') do
-  Time.gm(2012, 12, 23).yday == 358
+  assert_equal(358, Time.gm(2012, 12, 23).yday)
 end
 
 assert('Time#year', '15.2.19.7.32') do
-  Time.gm(2012, 12, 23).year == 2012
+  assert_equal(2012, Time.gm(2012, 12, 23).year)
 end
 
 assert('Time#zone', '15.2.19.7.33') do
-  Time.at(1300000000.0).utc.zone == 'UTC'
+  assert_equal('UTC', Time.at(1300000000.0).utc.zone)
 end
 
 # Not ISO specified
 
 assert('Time#to_s') do
-  Time.at(1300000000.0).utc.to_s == "Sun Mar 13 07:06:40 UTC 2011"
+  assert_equal("2003-04-05 06:07:08 UTC", Time.gm(2003,4,5,6,7,8,9).to_s)
 end
 
 assert('Time#inspect') do
-  Time.at(1300000000.0).utc.inspect == "Sun Mar 13 07:06:40 UTC 2011"
+  assert_match("2013-10-28 16:27:48 [+-][0-9][0-9][0-9][0-9]",
+               Time.local(2013,10,28,16,27,48).inspect)
 end
 
 assert('day of week methods') do
@@ -224,7 +259,7 @@ assert('2000 times 500us make a second') do
   2000.times do
     t += 0.0005
   end
-  t.usec == 0
+  assert_equal(0, t.usec)
 end
 
 assert('Time.gm with Dec 31 23:59:59 1969 raise ArgumentError') do
index 1811236..cbcca86 100644 (file)
@@ -1,3 +1,13 @@
+class BasicObject
+  def !=(other)
+    if self == other
+      false
+    else
+      true
+    end
+  end
+end
+
 class Module
    # 15.2.2.4.12
   def attr_accessor(*names)
index d598efc..6535d6d 100644 (file)
@@ -10,16 +10,16 @@ class Array
   # and pass the respective element.
   #
   # ISO 15.2.12.5.10
-  def each(&block)
-    return to_enum :each unless block
+  def each(&block)
+    return to_enum :each unless block
 
-    idx = 0
-    while idx < length
-      block.call(self[idx])
-      idx += 1
-    end
-    self
-  end
+    idx = 0
+    while idx < length
+      block.call(self[idx])
+      idx += 1
+    end
+    self
+  end
 
   ##
   # Calls the given block for each element of +self+
@@ -83,13 +83,15 @@ class Array
     self
   end
 
-  def _inspect
+  def _inspect(recur_list)
     size = self.size
     return "[]" if size == 0
+    return "[...]" if recur_list[self.object_id]
+    recur_list[self.object_id] = true
     ary=[]
     i=0
     while i<size
-      ary<<self[i].inspect
+      ary<<self[i]._inspect(recur_list)
       i+=1
     end
     "["+ary.join(", ")+"]"
@@ -99,11 +101,7 @@ class Array
   #
   # ISO 15.2.12.5.31 (x)
   def inspect
-    begin
-      self._inspect
-    rescue SystemStackError
-      "[...]"
-    end
+    self._inspect({})
   end
   # ISO 15.2.12.5.32 (x)
   alias to_s inspect
index 9bd74e1..15687e1 100644 (file)
@@ -65,22 +65,22 @@ module Enumerable
   end
 
   ##
-  # Call the given block for each element
-  # which is yield by +each+. Return
-  # +ifnone+ if no block value was true.
-  # Otherwise return the first block value
-  # which had was true.
+  # Return the first element for which
+  # value from the block is true. If no
+  # object matches, calls +ifnone+ and
+  # returns its result. Otherwise returns
+  # +nil+.
   #
   # ISO 15.3.2.2.4
   def detect(ifnone=nil, &block)
-    ret = ifnone
+    return to_enum :detect, ifnone unless block
+
     self.each{|*val|
       if block.call(*val)
-        ret = val.__svalue
-        break
+        return val.__svalue
       end
     }
-    ret
+    ifnone.call unless ifnone.nil?
   end
 
   ##
@@ -284,6 +284,8 @@ module Enumerable
   #
   # ISO 15.3.2.2.16
   def partition(&block)
+    return to_enum :partition unless block
+
     ary_T = []
     ary_F = []
     self.each{|*val|
@@ -304,6 +306,8 @@ module Enumerable
   #
   # ISO 15.3.2.2.17
   def reject(&block)
+    return to_enum :reject unless block
+
     ary = []
     self.each{|*val|
       ary.push(val.__svalue) unless block.call(*val)
index 609883e..7d64add 100644 (file)
@@ -140,7 +140,7 @@ class Hash
   def each_value(&block)
     return to_enum :each_value unless block
 
-    self.keys.each{|k| block.call(self[k])}
+    self.values.each{|v| block.call(v)}
     self
   end
 
@@ -186,15 +186,17 @@ class Hash
   end
 
   # internal method for Hash inspection
-  def _inspect
+  def _inspect(recur_list)
     return "{}" if self.size == 0
+    return "{...}" if recur_list[self.object_id]
+    recur_list[self.object_id] = true
     ary=[]
     keys=self.keys
+    vals=self.values
     size=keys.size
     i=0
     while i<size
-      k=keys[i]
-      ary<<(k._inspect + "=>" + self[k]._inspect)
+      ary<<(keys[i]._inspect(recur_list) + "=>" + vals[i]._inspect(recur_list))
       i+=1
     end
     "{"+ary.join(", ")+"}"
@@ -204,11 +206,7 @@ class Hash
  #
   # ISO 15.2.13.4.30 (x)
   def inspect
-    begin
-      self._inspect
-    rescue SystemStackError
-      "{...}"
-    end
+    self._inspect({})
   end
   # ISO 15.2.13.4.31 (x)
   alias to_s inspect
index 4700684..7c3ea94 100644 (file)
@@ -40,7 +40,7 @@ module Kernel
   end
 
   # internal method for inspect
-  def _inspect
+  def _inspect(_recur_list)
     self.inspect
   end
 
index e96decb..6fba0ad 100644 (file)
@@ -8,7 +8,7 @@ MRuby.each_target do
   file objfile("#{current_build_dir}/mrblib") => "#{current_build_dir}/mrblib.c"
   file "#{current_build_dir}/mrblib.c" => [mrbcfile, __FILE__] + Dir.glob("#{current_dir}/*.rb").sort do |t|
     _, _, *rbfiles = t.prerequisites
-    FileUtils.mkdir_p File.dirname(t.name)
+    mkdir_p File.dirname(t.name)
     open(t.name, 'w') do |f|
       _pp "GEN", "*.rb", "#{t.name.relative_path}"
       f.puts File.read("#{current_dir}/init_mrblib.c")
index 5a3c5eb..5926518 100644 (file)
@@ -105,14 +105,14 @@ module Integral
     return to_enum(:step, num, step) unless block
 
     i = __coerce_step_counter(num, step)
-    if num == nil
+    if num == self || step.infinite?
+      block.call(i) if step > 0 && i <= (num||i) || step < 0 && i >= (num||-i)
+    elsif num == nil
       while true
         block.call(i)
         i += step
       end
-      return self
-    end
-    if step > 0
+    elsif step > 0
       while i <= num
         block.call(i)
         i += step
index 5bd2521..392cc22 100644 (file)
@@ -26,7 +26,7 @@ class Range
       return self
     end
 
-    if val.kind_of?(String) && last.kind_of?(String) # fixnums are special
+    if val.kind_of?(String) && last.kind_of?(String) # strings are special
       if val.respond_to? :upto
         return val.upto(last, exclude_end?, &block)
       else
index 64e85c5..0e7c8dc 100644 (file)
@@ -3,24 +3,51 @@
 #
 # ISO 15.2.10
 class String
+  # ISO 15.2.10.3
   include Comparable
+
   ##
   # Calls the given block for each line
   # and pass the respective line.
   #
   # ISO 15.2.10.5.15
-  def each_line(rs = "\n", &block)
-    return to_enum(:each_line, rs, &block) unless block
-    return block.call(self) if rs.nil?
-    rs.__to_str
-    offset = 0
-    rs_len = rs.length
-    this = dup
-    while pos = this.index(rs, offset)
-      block.call(this[offset, pos + rs_len - offset])
-      offset = pos + rs_len
+  def each_line(separator = "\n", &block)
+    return to_enum(:each_line, separator) unless block
+
+    if separator.nil?
+      block.call(self)
+      return self
+    end
+    raise TypeError unless separator.is_a?(String)
+
+    paragraph_mode = false
+    if separator.empty?
+      paragraph_mode = true
+      separator = "\n\n"
+    end
+    start = 0
+    string = dup
+    self_len = length
+    sep_len = separator.length
+    should_yield_subclass_instances = self.class != String
+
+    while (pointer = string.index(separator, start))
+      pointer += sep_len
+      pointer += 1 while paragraph_mode && string[pointer] == "\n"
+      if should_yield_subclass_instances
+        block.call(self.class.new(string[start, pointer - start]))
+      else
+        block.call(string[start, pointer - start])
+      end
+      start = pointer
+    end
+    return self if start == self_len
+
+    if should_yield_subclass_instances
+      block.call(self.class.new(string[start, self_len - start]))
+    else
+      block.call(string[start, self_len - start])
     end
-    block.call(this[offset, this.size - offset]) if this.size > offset
     self
   end
 
@@ -103,18 +130,15 @@ class String
     self.replace(str)
   end
 
-  ##
-  # Calls the given block for each match of +pattern+
-  # If no block is given return an array with all
-  # matches of +pattern+.
-  #
-  # ISO 15.2.10.5.32
-  def scan(reg, &block)
-    ### *** TODO *** ###
-    unless Object.const_defined?(:Regexp)
-      raise NotImplementedError, "scan not available (yet)"
-    end
-  end
+#  ##
+#  # Calls the given block for each match of +pattern+
+#  # If no block is given return an array with all
+#  # matches of +pattern+.
+#  #
+#  # ISO 15.2.10.5.32
+#  def scan(pattern, &block)
+#    # TODO: String#scan is not implemented yet
+#  end
 
   ##
   # Replace only the first match of +pattern+ with
@@ -166,20 +190,9 @@ class String
   end
 
   ##
-  # Call the given block for each character of
-  # +self+.
-  def each_char(&block)
-    pos = 0
-    while pos < self.size
-      block.call(self[pos])
-      pos += 1
-    end
-    self
-  end
-
-  ##
   # Call the given block for each byte of +self+.
   def each_byte(&block)
+    return to_enum(:each_byte, &block) unless block
     bytes = self.bytes
     pos = 0
     while pos < bytes.size
@@ -189,86 +202,16 @@ class String
     self
   end
 
-  ##
-  # Modify +self+ by replacing the content of +self+.
-  # The portion of the string affected is determined using the same criteria as +String#[]+.
-  def []=(*args)
-    anum = args.size
-    if anum == 2
-      pos, value = args
-      case pos
-      when String
-        posnum = self.index(pos)
-        if posnum
-          b = self[0, posnum.to_i]
-          a = self[(posnum + pos.length)..-1]
-          self.replace([b, value, a].join(''))
-        else
-          raise IndexError, "string not matched"
-        end
-      when Range
-        head = pos.begin
-        tail = pos.end
-        tail += self.length if tail < 0
-        unless pos.exclude_end?
-          tail += 1
-        end
-        return self[head, tail-head]=value
-      else
-        pos += self.length if pos < 0
-        if pos < 0 || pos > self.length
-          raise IndexError, "index #{args[0]} out of string"
-        end
-        b = self[0, pos.to_i]
-        a = self[pos + 1..-1]
-        self.replace([b, value, a].join(''))
-      end
-      return value
-    elsif anum == 3
-      pos, len, value = args
-      pos += self.length if pos < 0
-      if pos < 0 || pos > self.length
-        raise IndexError, "index #{args[0]} out of string"
-      end
-      if len < 0
-        raise IndexError, "negative length #{len}"
-      end
-      b = self[0, pos.to_i]
-      a = self[pos + len..-1]
-      self.replace([b, value, a].join(''))
-      return value
-    else
-      raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)"
-    end
-  end
-
+  # those two methods requires Regexp that is optional in mruby
   ##
   # ISO 15.2.10.5.3
-  def =~(re)
-    re =~ self
-  end
+  #def =~(re)
+  # re =~ self
+  #end
 
   ##
   # ISO 15.2.10.5.27
-  def match(re, &block)
-    if String === re
-      if Object.const_defined?(:Regexp)
-        r = Regexp.new(re)
-        r.match(self, &block)
-      else
-        raise NotImplementedError, "String#match needs Regexp class"
-      end
-    else
-      re.match(self, &block)
-    end
-  end
-end
-
-##
-# String is comparable
-#
-# ISO 15.2.10.3
-module Comparable; end
-class String
-  include Comparable
+  #def match(re, &block)
+  #  re.match(self, &block)
+  #end
 end
index 62d4c0d..b87dda3 100644 (file)
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
 
   spec.summary       = %q{MRuby source code wrapper.}
   spec.description   = %q{MRuby source code wrapper for use with Ruby libs.}
-  spec.homepage      = "http://www.mruby.org/"
+  spec.homepage      = "https://mruby.org"
   spec.license       = "MIT"
 
   spec.files         = `git ls-files -z`.split("\x0")
diff --git a/third-party/mruby/oss-fuzz/config/mruby.dict b/third-party/mruby/oss-fuzz/config/mruby.dict
new file mode 100644 (file)
index 0000000..a332d35
--- /dev/null
@@ -0,0 +1,105 @@
+keyword___ENCODING__="__ENCODING__"
+keyword___FILE__="__FILE__"
+keyword___LINE__="__LINE__"
+keyword_BEGIN="BEGIN"
+keyword_END="END"
+keyword_alias="alias"
+keyword_and="and"
+keyword_begin="begin"
+keyword_break="break"
+keyword_case="case"
+keyword_class="class"
+keyword_def="def"
+keyword_do="do"
+keyword_else="else"
+keyword_elsif="elsif"
+keyword_end="end"
+keyword_ensure="ensure"
+keyword_false="false"
+keyword_for="for"
+keyword_if="if"
+keyword_in="in"
+keyword_module="module"
+keyword_next="next"
+keyword_nil="nil"
+keyword_not="not"
+keyword_or="or"
+keyword_redo="redo"
+keyword_rescue="rescue"
+keyword_retry="retry"
+keyword_return="return"
+keyword_self="self"
+keyword_super="super"
+keyword_then="then"
+keyword_true="true"
+keyword_undef="undef"
+keyword_unless="unless"
+keyword_until="until"
+keyword_when="when"
+keyword_while="while"
+keyword_yield="yield"
+
+operator_a=" !"
+operator_b=" ~"
+operator_c=" +"
+operator_d=" -"
+operator_e=" []"
+operator_f=" []="
+operator_g=" *"
+operator_h=" /"
+operator_i=" %"
+operator_j=" +-"
+operator_k=" >>"
+operator_l=" <<"
+operator_m=" &"
+operator_n=" ^"
+operator_o=" |"
+operator_p=" <="
+operator_q=" <>"
+operator_r=" >="
+operator_s=" <=>"
+operator_t=" =="
+operator_u=" ==="
+operator_v=" !="
+operator_w=" =~"
+operator_x=" !~"
+operator_y=" &&"
+operator_z=" ||"
+operator_aa=" .."
+operator_ab=" ..."
+operator_ac=" ?"
+operator_ad=" :"
+operator_ae=" ="
+operator_af=" %="
+operator_ag=" /="
+operator_ah=" -="
+operator_ai=" +="
+operator_aj=" |="
+operator_ak=" &="
+operator_al=" >>="
+operator_am=" <<="
+operator_an=" *="
+operator_ao=" &&="
+operator_ap=" ||="
+operator_aq=" **="
+operator_ar=" ^="
+operator_as=" not"
+operator_at=" or"
+operator_au=" and"
+operator_av=" if"
+operator_aw=" unless"
+operator_ax=" while"
+operator_ay=" until"
+operator_az=" begin"
+operator_ba=" end"
+
+snippet_1eq1=" 1=1"
+snippet_dollar=" $1"
+snippet_at=" @a"
+snippet_symbol=" :a"
+snippet_array=" [1,2]"
+snippet_block=" 1.times{|x| x}"
+snippet_multi=" 1*1"
+
+string_single_q=" 'a'"
+string_dbl_q=" \"a\""
diff --git a/third-party/mruby/oss-fuzz/config/mruby_fuzzer.options b/third-party/mruby/oss-fuzz/config/mruby_fuzzer.options
new file mode 100644 (file)
index 0000000..8658e71
--- /dev/null
@@ -0,0 +1,5 @@
+[libfuzzer]
+close_fd_mask = 3
+dict = mruby.dict
+fork = 1
+only_ascii = 1
diff --git a/third-party/mruby/oss-fuzz/config/mruby_proto_fuzzer.options b/third-party/mruby/oss-fuzz/config/mruby_proto_fuzzer.options
new file mode 100644 (file)
index 0000000..4ced851
--- /dev/null
@@ -0,0 +1,4 @@
+[libfuzzer]
+close_fd_mask = 3
+dict = mruby.dict
+fork = 1
diff --git a/third-party/mruby/oss-fuzz/mruby_fuzzer.c b/third-party/mruby/oss-fuzz/mruby_fuzzer.c
new file mode 100644 (file)
index 0000000..9d3d44a
--- /dev/null
@@ -0,0 +1,18 @@
+#include <stdlib.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/compile.h>
+
+int LLVMFuzzerTestOneInput(uint8_t *Data, size_t size) {
+    if (size < 1) {
+        return 0;
+    }
+    char *code = malloc(size+1);
+    memcpy(code, Data, size);
+    code[size] = '\0';
+    mrb_state *mrb = mrb_open();
+    mrb_load_string(mrb, code);
+    mrb_close(mrb);
+    free(code);
+    return 0;
+}
diff --git a/third-party/mruby/oss-fuzz/mruby_proto_fuzzer.cpp b/third-party/mruby/oss-fuzz/mruby_proto_fuzzer.cpp
new file mode 100644 (file)
index 0000000..2999c54
--- /dev/null
@@ -0,0 +1,44 @@
+#include <string>
+#include <iostream>
+#include <fstream>
+
+#include <mruby.h>
+#include <mruby/compile.h>
+
+#include "libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h"
+#include "ruby.pb.h"
+#include "proto_to_ruby.h"
+
+using namespace ruby_fuzzer;
+using namespace std;
+
+int FuzzRB(const uint8_t *Data, size_t size) {
+       mrb_value v;
+       mrb_state *mrb = mrb_open();
+       if (!mrb)
+               return 0;
+
+       char *code = (char *)malloc(size+1);
+       if (!code)
+               return 0;
+       memcpy(code, Data, size);
+       code[size] = '\0';
+
+       if (const char *dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) {
+               // With libFuzzer binary run this to generate an RB file x.rb:
+               // PROTO_FUZZER_DUMP_PATH=x.rb ./a.out proto-input
+               std::ofstream of(dump_path);
+               of.write(code, size);
+       }
+       v = mrb_load_string(mrb, code);
+       mrb_close(mrb);
+
+       free(code);
+       return 0;
+}
+
+DEFINE_PROTO_FUZZER(const Function &function) {
+       protoConverter converter;
+       auto s = converter.FunctionToString(function);
+       (void)FuzzRB((const uint8_t*)s.data(), s.size());
+}
diff --git a/third-party/mruby/oss-fuzz/proto_to_ruby.cpp b/third-party/mruby/oss-fuzz/proto_to_ruby.cpp
new file mode 100644 (file)
index 0000000..92ad039
--- /dev/null
@@ -0,0 +1,455 @@
+#include "proto_to_ruby.h"
+
+using namespace ruby_fuzzer;
+
+std::string protoConverter::removeSpecial(const std::string &x)
+{
+       std::string tmp(x);
+       if (!tmp.empty())
+               tmp.erase(std::remove_if(tmp.begin(), tmp.end(),
+                                        [](char c) { return !(std::isalpha(c) || std::isdigit(c)); } ), tmp.end());
+       return tmp;
+}
+
+void protoConverter::visit(ArrType const& x)
+{
+       if (x.elements_size() > 0) {
+               int i = x.elements_size();
+               m_output << "[";
+               for (auto &e : x.elements()) {
+                       i--;
+                       if (i == 0) {
+                               visit(e);
+                       } else {
+                               visit(e);
+                               m_output << ", ";
+                       }
+               }
+               m_output << "]";
+       } else {
+               m_output << "[1]";
+       }
+}
+
+void protoConverter::visit(Array const& x)
+{
+       switch (x.arr_func()) {
+               case Array::FLATTEN:
+                       visit(x.arr_arg());
+                       m_output << ".flatten";
+                       break;
+               case Array::COMPACT:
+                       visit(x.arr_arg());
+                       m_output << ".compact";
+                       break;
+               case Array::FETCH:
+                       visit(x.arr_arg());
+                       m_output << ".fetch";
+                       break;
+               case Array::FILL:
+                       visit(x.arr_arg());
+                       m_output << ".fill";
+                       break;
+               case Array::ROTATE:
+                       visit(x.arr_arg());
+                       m_output << ".rotate";
+                       break;
+               case Array::ROTATE_E:
+                       visit(x.arr_arg());
+                       m_output << ".rotate!";
+                       break;
+               case Array::DELETEIF:
+                       visit(x.arr_arg());
+                       m_output << ".delete_if";
+                       break;
+               case Array::INSERT:
+                       visit(x.arr_arg());
+                       m_output << ".insert";
+                       break;
+               case Array::BSEARCH:
+                       visit(x.arr_arg());
+                       m_output << ".bsearch";
+                       break;
+               case Array::KEEPIF:
+                       visit(x.arr_arg());
+                       m_output << ".keep_if";
+                       break;
+               case Array::SELECT:
+                       visit(x.arr_arg());
+                       m_output << ".select";
+                       break;
+               case Array::VALUES_AT:
+                       visit(x.arr_arg());
+                       m_output << ".values_at";
+                       break;
+               case Array::BLOCK:
+                       visit(x.arr_arg());
+                       m_output << ".index";
+                       break;
+               case Array::DIG:
+                       visit(x.arr_arg());
+                       m_output << ".dig";
+                       break;
+               case Array::SLICE:
+                       visit(x.arr_arg());
+                       m_output << ".slice";
+                       break;
+               case Array::PERM:
+                       visit(x.arr_arg());
+                       m_output << ".permutation";
+                       break;
+               case Array::COMB:
+                       visit(x.arr_arg());
+                       m_output << ".combination";
+                       break;
+               case Array::ASSOC:
+                       visit(x.arr_arg());
+                       m_output << ".assoc";
+                       break;
+               case Array::RASSOC:
+                       visit(x.arr_arg());
+                       m_output << ".rassoc";
+                       break;
+       }
+       m_output << "(";
+       visit(x.val_arg());
+       m_output << ")";
+}
+
+void protoConverter::visit(AssignmentStatement const& x)
+{
+       m_output << "var_" << m_numLiveVars << " = ";
+       visit(x.rvalue());
+       m_numVarsPerScope.top()++;
+       m_numLiveVars++;
+       m_output << "\n";
+}
+
+void protoConverter::visit(BinaryOp const& x)
+{
+       m_output << "(";
+       visit(x.left());
+       switch (x.op()) {
+               case BinaryOp::ADD: m_output << " + "; break;
+               case BinaryOp::SUB: m_output << " - "; break;
+               case BinaryOp::MUL: m_output << " * "; break;
+               case BinaryOp::DIV: m_output << " / "; break;
+               case BinaryOp::MOD: m_output << " % "; break;
+               case BinaryOp::XOR: m_output << " ^ "; break;
+               case BinaryOp::AND: m_output << " and "; break;
+               case BinaryOp::OR: m_output << " or "; break;
+               case BinaryOp::EQ: m_output << " == "; break;
+               case BinaryOp::NE: m_output << " != "; break;
+               case BinaryOp::LE: m_output << " <= "; break;
+               case BinaryOp::GE: m_output << " >= "; break;
+               case BinaryOp::LT: m_output << " < "; break;
+               case BinaryOp::GT: m_output << " > "; break;
+               case BinaryOp::RS: m_output << " >> "; break;
+       }
+       visit(x.right());
+       m_output << ")";
+}
+
+void protoConverter::visit(BuiltinFuncs const& x)
+{
+       switch (x.bifunc_oneof_case()) {
+               case BuiltinFuncs::kOs:
+                       visit(x.os());
+                       break;
+               case BuiltinFuncs::kTime:
+                       visit(x.time());
+                       break;
+               case BuiltinFuncs::kArr:
+                       visit(x.arr());
+                       break;
+               case BuiltinFuncs::kMops:
+                       visit(x.mops());
+                       break;
+               case BuiltinFuncs::BIFUNC_ONEOF_NOT_SET:
+                       m_output << "1";
+                       break;
+       }
+       m_output << "\n";
+}
+
+void protoConverter::visit(Const const& x)
+{
+       switch (x.const_oneof_case()) {
+               case Const::kIntLit:
+                       m_output << "(" << (x.int_lit() % 13) << ")";
+                       break;
+               case Const::kBoolVal:
+                       m_output << "(" << x.bool_val() << ")";
+                       break;
+               case Const::CONST_ONEOF_NOT_SET:
+                       m_output << "1";
+                       break;
+       }
+}
+
+void protoConverter::visit(Function const& x)
+{
+       m_output << "def foo()\nvar_0 = 1\n";
+       visit(x.statements());
+       m_output << "end\n";
+       m_output << "foo\n";
+}
+
+void protoConverter::visit(HashType const& x)
+{
+       if (x.keyval_size() > 0) {
+               int i = x.keyval_size();
+               m_output << "{";
+               for (auto &e : x.keyval()) {
+                       i--;
+                       if (i == 0) {
+                               visit(e);
+                       }
+                       else {
+                               visit(e);
+                               m_output << ", ";
+                       }
+               }
+               m_output << "}";
+       }
+}
+
+void protoConverter::visit(IfElse const& x)
+{
+       m_output << "if ";
+       visit(x.cond());
+       m_output << "\n";
+       visit(x.if_body());
+       m_output << "\nelse\n";
+       visit(x.else_body());
+       m_output << "\nend\n";
+}
+
+void protoConverter::visit(KVPair const& x)
+{
+       m_output << "\"" << removeSpecial(x.key()) << "\"";
+       m_output << " => ";
+       m_output << "\"" << removeSpecial(x.val()) << "\"";
+}
+
+void protoConverter::visit(MathConst const& x)
+{
+       switch (x.math_const()) {
+               case MathConst::PI:
+                       m_output << "Math::PI";
+                       break;
+               case MathConst::E:
+                       m_output << "Math::E";
+                       break;
+       }
+}
+
+void protoConverter::visit(MathOps const& x)
+{
+       switch (x.math_op()) {
+               case MathOps::CBRT:
+                       m_output << "Math.cbrt(";
+                       visit(x.math_arg());
+                       m_output << ")";
+                       break;
+               case MathOps::COS:
+                       m_output << "Math.cos(";
+                       visit(x.math_arg());
+                       m_output << ")";
+                       break;
+               case MathOps::ERF:
+                       m_output << "Math.erf(";
+                       visit(x.math_arg());
+                       m_output << ")";
+                       break;
+               case MathOps::ERFC:
+                       m_output << "Math.erfc(";
+                       visit(x.math_arg());
+                       m_output << ")";
+                       break;
+               case MathOps::LOG:
+                       m_output << "Math.log(";
+                       visit(x.math_arg());
+                       m_output << ")";
+                       break;
+               case MathOps::LOG10:
+                       m_output << "Math.log10(";
+                       visit(x.math_arg());
+                       m_output << ")";
+                       break;
+               case MathOps::LOG2:
+                       m_output << "Math.log2(";
+                       visit(x.math_arg());
+                       m_output << ")";
+                       break;
+               case MathOps::SIN:
+                       m_output << "Math.sin(";
+                       visit(x.math_arg());
+                       m_output << ")";
+                       break;
+               case MathOps::SQRT:
+                       m_output << "Math.sqrt(";
+                       visit(x.math_arg());
+                       m_output << ")";
+                       break;
+               case MathOps::TAN:
+                       m_output << "Math.tan(";
+                       visit(x.math_arg());
+                       m_output << ")";
+                       break;
+       }
+}
+
+void protoConverter::visit(MathType const& x)
+{
+       switch (x.math_arg_oneof_case()) {
+               case MathType::kMathRval:
+                       visit(x.math_rval());
+                       break;
+               case MathType::kMathConst:
+                       visit(x.math_const());
+                       break;
+               case MathType::MATH_ARG_ONEOF_NOT_SET:
+                       m_output << "1";
+                       break;
+       }
+}
+
+void protoConverter::visit(ObjectSpace const& x)
+{
+       switch (x.os_func()) {
+               case ObjectSpace::COUNT:
+                       m_output << "ObjectSpace.count_objects";
+                       break;
+       }
+       m_output << "(";
+       visit(x.os_arg());
+       m_output << ")" << "\n";
+}
+
+void protoConverter::visit(Rvalue const& x)
+{
+       switch (x.rvalue_oneof_case()) {
+               case Rvalue::kVarref:
+                       visit(x.varref());
+                       break;
+               case Rvalue::kCons:
+                       visit(x.cons());
+                       break;
+               case Rvalue::kBinop:
+                       visit(x.binop());
+                       break;
+               case Rvalue::RVALUE_ONEOF_NOT_SET:
+                       m_output << "1";
+                       break;
+       }
+}
+
+void protoConverter::visit(Statement const& x)
+{
+       switch (x.stmt_oneof_case()) {
+               case Statement::kAssignment:
+                       visit(x.assignment());
+                       break;
+               case Statement::kIfelse:
+                       visit(x.ifelse());
+                       break;
+               case Statement::kTernaryStmt:
+                       visit(x.ternary_stmt());
+                       break;
+               case Statement::kBuiltins:
+                       visit(x.builtins());
+                       break;
+               case Statement::kBlockstmt:
+                       visit(x.blockstmt());
+                       break;
+               case Statement::STMT_ONEOF_NOT_SET:
+                       break;
+       }
+       m_output << "\n";
+}
+
+void protoConverter::visit(StatementSeq const& x)
+{
+       if (x.statements_size() > 0) {
+               m_numVarsPerScope.push(0);
+               m_output << "@scope ||= begin\n";
+               for (auto &st : x.statements())
+                       visit(st);
+               m_output << "end\n";
+               m_numLiveVars -= m_numVarsPerScope.top();
+               m_numVarsPerScope.pop();
+       }
+}
+
+void protoConverter::visit(StringExtNoArg const& x)
+{
+       m_output << "\"" << removeSpecial(x.str_arg()) << "\"";
+       switch (x.str_op()) {
+               case StringExtNoArg::DUMP:
+                       m_output << ".dump";
+                       break;
+               case StringExtNoArg::STRIP:
+                       m_output << ".strip";
+                       break;
+               case StringExtNoArg::LSTRIP:
+                       m_output << ".lstrip";
+                       break;
+               case StringExtNoArg::RSTRIP:
+                       m_output << ".rstrip";
+                       break;
+               case StringExtNoArg::STRIPE:
+                       m_output << ".strip!";
+                       break;
+               case StringExtNoArg::LSTRIPE:
+                       m_output << ".lstrip!";
+                       break;
+               case StringExtNoArg::RSTRIPE:
+                       m_output << ".rstrip!";
+                       break;
+               case StringExtNoArg::SWAPCASE:
+                       m_output << ".swapcase";
+                       break;
+               case StringExtNoArg::SWAPCASEE:
+                       m_output << ".swapcase!";
+                       break;
+               case StringExtNoArg::SQUEEZE:
+                       m_output << ".squeeze";
+                       break;
+       }
+}
+
+void protoConverter::visit(Ternary const& x)
+{
+       m_output << "(";
+       visit(x.tern_cond());
+       m_output << " ? ";
+       visit(x.t_branch());
+       m_output << " : ";
+       visit(x.f_branch());
+       m_output << ")\n";
+}
+
+void protoConverter::visit(Time const& x)
+{
+       switch (x.t_func()) {
+               case Time::AT:
+                       m_output << "Time.at";
+                       break;
+               case Time::GM:
+                       m_output << "Time.gm";
+                       break;
+       }
+       m_output << "(" << (x.t_arg()% 13) << ")" << "\n";
+}
+
+void protoConverter::visit(VarRef const& x)
+{
+       m_output << "var_" << (static_cast<uint32_t>(x.varnum()) % m_numLiveVars);
+}
+
+std::string protoConverter::FunctionToString(Function const& input)
+{
+       visit(input);
+       return m_output.str();
+}
diff --git a/third-party/mruby/oss-fuzz/proto_to_ruby.h b/third-party/mruby/oss-fuzz/proto_to_ruby.h
new file mode 100644 (file)
index 0000000..01f9d68
--- /dev/null
@@ -0,0 +1,55 @@
+#include <cstdint>
+#include <cstddef>
+#include <string>
+#include <ostream>
+#include <sstream>
+#include <stack>
+#include "ruby.pb.h"
+
+namespace ruby_fuzzer {
+       class protoConverter
+       {
+       public:
+               protoConverter() {
+                       m_numLiveVars = 1;
+                       m_numVarsPerScope.push(m_numLiveVars);
+               }
+               protoConverter(protoConverter const& x) {
+                       m_numLiveVars = x.m_numLiveVars;
+                       m_numVarsPerScope = x.m_numVarsPerScope;
+               }
+               ~protoConverter() {}
+               std::string FunctionToString(Function const& _input);
+
+       private:
+               void visit(ArrType const&);
+               void visit(Array const&);
+               void visit(AssignmentStatement const&);
+               void visit(BinaryOp const&);
+               void visit(BuiltinFuncs const&);
+               void visit(Const const&);
+               void visit(Function const&);
+               void visit(HashType const&);
+               void visit(IfElse const&);
+               void visit(KVPair const&);
+               void visit(MathConst const&);
+               void visit(MathOps const&);
+               void visit(MathType const&);
+               void visit(ObjectSpace const&);
+               void visit(Rvalue const&);
+               void visit(Statement const&);
+               void visit(StatementSeq const&);
+               void visit(StringExtNoArg const&);
+               void visit(Ternary const&);
+               void visit(Time const&);
+               void visit(VarRef const&);
+               template <class T>
+               void visit(google::protobuf::RepeatedPtrField<T> const& _repeated_field);
+
+               std::string removeSpecial(const std::string &x);
+
+               std::ostringstream m_output;
+               std::stack<uint8_t> m_numVarsPerScope;
+               int32_t m_numLiveVars;
+       };
+}
diff --git a/third-party/mruby/oss-fuzz/ruby.proto b/third-party/mruby/oss-fuzz/ruby.proto
new file mode 100644 (file)
index 0000000..d9b0804
--- /dev/null
@@ -0,0 +1,201 @@
+syntax = "proto2";
+
+message VarRef {
+  required int32 varnum = 1;
+}
+
+message ArrType {
+    repeated Const elements = 1;
+}
+
+message KVPair {
+    required string key = 1;
+    required string val = 2;
+}
+
+message HashType {
+    repeated KVPair keyval = 1;
+}
+
+message StringExtNoArg {
+  enum StrExtOp {
+    DUMP = 0;
+    STRIP = 1;
+    LSTRIP = 2;
+    RSTRIP = 3;
+    STRIPE = 4;
+    LSTRIPE = 5;
+    RSTRIPE = 6;
+    SWAPCASE = 7;
+    SWAPCASEE = 8;
+    SQUEEZE = 9;
+  }
+  required StrExtOp str_op = 1;
+  required string str_arg = 2;
+}
+
+message MathConst {
+    enum MathConstLit {
+        PI = 0;
+        E = 1;
+    }
+    required MathConstLit math_const = 1;
+}
+
+message Const {
+    oneof const_oneof {
+        uint32 int_lit = 1;
+        bool bool_val = 4;
+    }
+}
+
+message BinaryOp {
+  enum Op {
+    ADD = 0;
+    SUB = 1;
+    MUL = 2;
+    DIV = 3;
+    MOD = 4;
+    XOR = 5;
+    AND = 6;
+    OR = 7;
+    EQ = 8;
+    NE = 9;
+    LE = 10;
+    GE = 11;
+    LT = 12;
+    GT = 13;
+    RS = 14;
+  };
+  required Op op = 1;
+  required Rvalue left = 2;
+  required Rvalue right = 3;
+}
+
+message Rvalue {
+  oneof rvalue_oneof {
+    VarRef varref = 1;
+    Const cons = 2;
+    BinaryOp binop = 3;
+  }
+}
+
+message AssignmentStatement {
+  required Rvalue rvalue = 2;
+}
+
+
+message IfElse {
+  required Rvalue cond = 1;
+  required StatementSeq if_body = 2;
+  required StatementSeq else_body = 3;
+}
+
+//TODO: Add Switch statement
+//message Switch {
+//    required Rvalue switch_var = 1;
+//    repeated Rvalue cond = 2;
+//}
+
+message Ternary {
+    required Rvalue tern_cond = 1;
+    required Rvalue t_branch = 2;
+    required Rvalue f_branch = 3;
+}
+
+message ObjectSpace {
+    enum OS_methods {
+        COUNT = 1;
+    }
+    required OS_methods os_func = 1;
+    required HashType os_arg = 2;
+}
+
+message Time {
+    enum T_methods {
+        AT = 1;
+        GM = 2;
+    }
+    required T_methods t_func = 1;
+    required uint32 t_arg = 2;
+}
+
+message Array {
+    enum Arr_methods {
+        FLATTEN = 1;
+        COMPACT = 2;
+        FETCH = 3;
+        FILL = 4;
+        ROTATE = 5;
+        ROTATE_E = 6;
+        DELETEIF = 7;
+        INSERT = 8;
+        BSEARCH = 9;
+        KEEPIF = 10;
+        SELECT = 11;
+        VALUES_AT = 12;
+        BLOCK = 13;
+        DIG = 14;
+        SLICE = 15;
+        PERM = 16;
+        COMB = 17;
+        ASSOC = 18;
+        RASSOC = 19;
+    }
+    required Arr_methods arr_func = 1;
+    required ArrType  arr_arg = 2;
+    required Rvalue   val_arg = 3;
+}
+
+message MathType {
+    oneof math_arg_oneof {
+        Rvalue math_rval = 2;
+        MathConst math_const = 3;
+    }
+}
+
+message MathOps {
+    enum Mops {
+      CBRT = 1;
+      COS = 2;
+      ERF = 3;
+      ERFC = 4;
+      LOG = 5;
+      LOG10 = 6;
+      LOG2 = 7;
+      SIN = 8;
+      SQRT = 9;
+      TAN = 10;
+    }
+    required Mops math_op = 1;
+    required MathType math_arg = 2;
+}
+
+message BuiltinFuncs {
+    oneof bifunc_oneof {
+        ObjectSpace os = 1;
+        Time time = 2;
+        Array arr = 3;
+        MathOps mops = 4;
+    }
+}
+
+message Statement {
+  oneof stmt_oneof {
+    AssignmentStatement assignment = 1;
+    IfElse              ifelse     = 2;
+    Ternary             ternary_stmt = 3;
+    BuiltinFuncs        builtins = 4;
+    StatementSeq        blockstmt = 5;
+  }
+}
+
+message StatementSeq {
+  repeated Statement statements = 1;
+}
+
+message Function {
+  required StatementSeq statements = 1;
+}
+
+package ruby_fuzzer;
index 707820a..dae2fbf 100644 (file)
@@ -9,6 +9,8 @@
 #include <mruby/class.h>
 #include <mruby/string.h>
 #include <mruby/range.h>
+#include <mruby/proc.h>
+#include <mruby/opcode.h>
 #include "value_array.h"
 
 #define ARY_DEFAULT_LEN   4
@@ -120,9 +122,7 @@ ary_fill_with_nil(mrb_value *ptr, mrb_int size)
 static void
 ary_modify_check(mrb_state *mrb, struct RArray *a)
 {
-  if (MRB_FROZEN_P(a)) {
-    mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen array");
-  }
+  mrb_check_frozen(mrb, a);
 }
 
 static void
@@ -388,7 +388,7 @@ ary_replace(mrb_state *mrb, struct RArray *a, struct RArray *b)
     mrb_write_barrier(mrb, (struct RBasic*)a);
     return;
   }
-  if (!MRB_FROZEN_P(b) && len > ARY_REPLACE_SHARED_MIN) {
+  if (!mrb_frozen_p(b) && len > ARY_REPLACE_SHARED_MIN) {
     ary_make_shared(mrb, b);
     goto shared_b;
   }
@@ -631,11 +631,13 @@ mrb_ary_unshift_m(mrb_state *mrb, mrb_value self)
     ptr = a->as.heap.ptr;
   }
   else {
+    mrb_bool same = vals == ARY_PTR(a);
     ary_modify(mrb, a);
     if (ARY_CAPA(a) < len + alen)
       ary_expand_capa(mrb, a, len + alen);
     ptr = ARY_PTR(a);
     value_move(ptr + alen, ptr, len);
+    if (same) vals = ptr;
   }
   array_copy(ptr, vals, alen);
   ARY_SET_LEN(a, len+alen);
@@ -670,7 +672,7 @@ mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val)
   if (n < 0) {
     n += len;
     if (n < 0) {
-      mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of array", mrb_fixnum_value(n - len));
+      mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of array", n - len);
     }
   }
   if (len <= n) {
@@ -702,7 +704,7 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val
   ary_modify(mrb, a);
 
   /* len check */
-  if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%S)", mrb_fixnum_value(len));
+  if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%i)", len);
 
   /* range check */
   if (head < 0) {
@@ -730,13 +732,17 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val
       argv = ARY_PTR(r);
     }
   }
+  else if (mrb_undef_p(rpl)) {
+    argc = 0;
+    argv = NULL;
+  }
   else {
     argc = 1;
     argv = &rpl;
   }
   if (head >= alen) {
     if (head > ARY_MAX_SIZE - argc) {
-      mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(head));
+      mrb_raisef(mrb, E_INDEX_ERROR, "index %i too big", head);
     }
     len = head + argc;
     if (len > ARY_CAPA(a)) {
@@ -752,7 +758,7 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val
     mrb_int newlen;
 
     if (alen - len > ARY_MAX_SIZE - argc) {
-      mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(alen + argc - len));
+      mrb_raisef(mrb, E_INDEX_ERROR, "index %i too big", alen + argc - len);
     }
     newlen = alen + argc - len;
     if (newlen > ARY_CAPA(a)) {
@@ -802,6 +808,13 @@ ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len)
   return mrb_obj_value(b);
 }
 
+mrb_value
+mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len)
+{
+  struct RArray *a = mrb_ary_ptr(ary);
+  return ary_subseq(mrb, a, beg, len);
+}
+
 static mrb_int
 aget_index(mrb_state *mrb, mrb_value index)
 {
@@ -853,14 +866,16 @@ static mrb_value
 mrb_ary_aget(mrb_state *mrb, mrb_value self)
 {
   struct RArray *a = mrb_ary_ptr(self);
-  mrb_int i, len, alen;
+  mrb_int i;
+  mrb_int len, alen;
   mrb_value index;
 
-  if (mrb_get_args(mrb, "o|i", &index, &len) == 1) {
+  if (mrb_get_argc(mrb) == 1) {
+    index = mrb_get_arg1(mrb);
     switch (mrb_type(index)) {
       /* a[n..m] */
     case MRB_TT_RANGE:
-      if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == 1) {
+      if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
         return ary_subseq(mrb, a, i, len);
       }
       else {
@@ -873,6 +888,7 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self)
     }
   }
 
+  mrb_get_args(mrb, "oi", &index, &len);
   i = aget_index(mrb, index);
   alen = ARY_LEN(a);
   if (i < 0) i += alen;
@@ -926,22 +942,26 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self)
   mrb_int i, len;
 
   mrb_ary_modify(mrb, mrb_ary_ptr(self));
-  if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) {
+  if (mrb_get_argc(mrb) == 2) {
+    mrb_value *vs = mrb_get_argv(mrb);
+    v1 = vs[0]; v2 = vs[1];
+
     /* a[n..m] = v */
     switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) {
-    case 0:                   /* not range */
+    case MRB_RANGE_TYPE_MISMATCH:
       mrb_ary_set(mrb, self, aget_index(mrb, v1), v2);
       break;
-    case 1:                   /* range */
+    case MRB_RANGE_OK:
       mrb_ary_splice(mrb, self, i, len, v2);
       break;
-    case 2:                   /* out of range */
-      mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1);
+    case MRB_RANGE_OUT:
+      mrb_raisef(mrb, E_RANGE_ERROR, "%v out of range", v1);
       break;
     }
     return v2;
   }
 
+  mrb_get_args(mrb, "ooo", &v1, &v2, &v3);
   /* a[n,m] = v */
   mrb_ary_splice(mrb, self, aget_index(mrb, v1), aget_index(mrb, v2), v3);
   return v3;
@@ -1025,10 +1045,9 @@ mrb_ary_last(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_ary_index_m(mrb_state *mrb, mrb_value self)
 {
-  mrb_value obj;
+  mrb_value obj = mrb_get_arg1(mrb);
   mrb_int i;
 
-  mrb_get_args(mrb, "o", &obj);
   for (i = 0; i < RARRAY_LEN(self); i++) {
     if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) {
       return mrb_fixnum_value(i);
@@ -1040,10 +1059,9 @@ mrb_ary_index_m(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_ary_rindex_m(mrb_state *mrb, mrb_value self)
 {
-  mrb_value obj;
+  mrb_value obj = mrb_get_arg1(mrb);
   mrb_int i, len;
 
-  mrb_get_args(mrb, "o", &obj);
   for (i = RARRAY_LEN(self) - 1; i >= 0; i--) {
     if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) {
       return mrb_fixnum_value(i);
@@ -1105,7 +1123,6 @@ mrb_ary_clear(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_ary_clear_m(mrb_state *mrb, mrb_value self)
 {
-  mrb_get_args(mrb, "");
   return mrb_ary_clear(mrb, self);
 }
 
@@ -1218,9 +1235,8 @@ mrb_ary_join_m(mrb_state *mrb, mrb_value ary)
 static mrb_value
 mrb_ary_eq(mrb_state *mrb, mrb_value ary1)
 {
-  mrb_value ary2;
+  mrb_value ary2 = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &ary2);
   if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
   if (!mrb_array_p(ary2)) {
     return mrb_false_value();
@@ -1233,9 +1249,8 @@ mrb_ary_eq(mrb_state *mrb, mrb_value ary1)
 static mrb_value
 mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
 {
-  mrb_value ary2;
+  mrb_value ary2 = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &ary2);
   if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0);
   if (!mrb_array_p(ary2)) {
     return mrb_nil_value();
@@ -1248,7 +1263,6 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
 static mrb_value
 mrb_ary_svalue(mrb_state *mrb, mrb_value ary)
 {
-  mrb_get_args(mrb, "");
   switch (RARRAY_LEN(ary)) {
   case 0:
     return mrb_nil_value();
@@ -1259,46 +1273,96 @@ mrb_ary_svalue(mrb_state *mrb, mrb_value ary)
   }
 }
 
+static const mrb_code each_iseq[] = {
+  OP_ENTER, 0x0, 0x00, 0x1,  /* OP_ENTER     0:0:0:0:0:0:1 */
+  OP_JMPIF, 0x1, 0x0, 19,    /* OP_JMPIF     R1  19 */
+  OP_LOADSELF, 0x3,          /* OP_LOADSELF  R3 */
+  OP_LOADSYM, 0x4, 0x0,      /* OP_LOADSYM   R4  :each*/
+  OP_SEND, 0x3, 0x1, 0x1,    /* OP_SEND      R3  :to_enum   1 */
+  OP_RETURN, 0x3,            /* OP_RETURN    R3 */
+  OP_LOADI_0, 0x2,           /* OP_LOADI_0   R2 */
+  OP_JMP, 0x0, 43,           /* OP_JMP       49 */
+  OP_MOVE, 0x3, 0x1,         /* OP_MOVE      R3  R1 */
+  OP_LOADSELF, 0x4,          /* OP_LOADSELF  R4 */
+  OP_MOVE, 0x5, 0x2,         /* OP_MOVE      R5  R2 */
+  OP_SEND, 0x4, 0x2, 0x1,    /* OP_SEND      R4  :[]        1 */
+  OP_SEND, 0x3, 0x3, 0x1,    /* OP_SEND      R3  :call      1 */
+  OP_ADDI, 0x2, 1,           /* OP_ADDI      R3  1 */
+  OP_MOVE, 0x3, 0x2,         /* OP_MOVE      R3  R2 */
+  OP_LOADSELF, 0x4,          /* OP_LOADSELF  R4 */
+  OP_SEND, 0x4, 0x4, 0x0,    /* OP_SEND      R4  :length    0 */
+  OP_LT, 0x3,                /* OP_LT        R3 */
+  OP_JMPIF, 0x3, 0x0, 24,    /* OP_JMPIF     R3  24 */
+  OP_RETURN, 0x0             /* OP_RETURN    R3 */
+};
+
+static void
+init_ary_each(mrb_state *mrb, struct RClass *ary)
+{
+  struct RProc *p;
+  mrb_method_t m;
+  mrb_irep *each_irep = (mrb_irep*)mrb_malloc(mrb, sizeof(mrb_irep));
+  static const mrb_irep mrb_irep_zero = { 0 };
+
+  *each_irep = mrb_irep_zero;
+  each_irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*5);
+  each_irep->syms[0] = mrb_intern_lit(mrb, "each");
+  each_irep->syms[1] = mrb_intern_lit(mrb, "to_enum");
+  each_irep->syms[2] = mrb_intern_lit(mrb, "[]");
+  each_irep->syms[3] = mrb_intern_lit(mrb, "call");
+  each_irep->syms[4] = mrb_intern_lit(mrb, "length");
+  each_irep->slen = 5;
+  each_irep->flags = MRB_ISEQ_NO_FREE;
+  each_irep->iseq = each_iseq;
+  each_irep->ilen = sizeof(each_iseq);
+  each_irep->nregs = 7;
+  each_irep->nlocals = 3;
+  p = mrb_proc_new(mrb, each_irep);
+  p->flags |= MRB_PROC_SCOPE | MRB_PROC_STRICT;
+  MRB_METHOD_FROM_PROC(m, p);
+  mrb_define_method_raw(mrb, ary, mrb_intern_lit(mrb, "each"), m);
+}
+
 void
 mrb_init_array(mrb_state *mrb)
 {
   struct RClass *a;
 
-  mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class);            /* 15.2.12 */
+  mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class);              /* 15.2.12 */
   MRB_SET_INSTANCE_TT(a, MRB_TT_ARRAY);
 
-  mrb_define_class_method(mrb, a, "[]",        mrb_ary_s_create,     MRB_ARGS_ANY());  /* 15.2.12.4.1 */
-
-  mrb_define_method(mrb, a, "+",               mrb_ary_plus,         MRB_ARGS_REQ(1)); /* 15.2.12.5.1  */
-  mrb_define_method(mrb, a, "*",               mrb_ary_times,        MRB_ARGS_REQ(1)); /* 15.2.12.5.2  */
-  mrb_define_method(mrb, a, "<<",              mrb_ary_push_m,       MRB_ARGS_REQ(1)); /* 15.2.12.5.3  */
-  mrb_define_method(mrb, a, "[]",              mrb_ary_aget,         MRB_ARGS_ANY());  /* 15.2.12.5.4  */
-  mrb_define_method(mrb, a, "[]=",             mrb_ary_aset,         MRB_ARGS_ANY());  /* 15.2.12.5.5  */
-  mrb_define_method(mrb, a, "clear",           mrb_ary_clear_m,      MRB_ARGS_NONE()); /* 15.2.12.5.6  */
-  mrb_define_method(mrb, a, "concat",          mrb_ary_concat_m,     MRB_ARGS_REQ(1)); /* 15.2.12.5.8  */
-  mrb_define_method(mrb, a, "delete_at",       mrb_ary_delete_at,    MRB_ARGS_REQ(1)); /* 15.2.12.5.9  */
-  mrb_define_method(mrb, a, "empty?",          mrb_ary_empty_p,      MRB_ARGS_NONE()); /* 15.2.12.5.12 */
-  mrb_define_method(mrb, a, "first",           mrb_ary_first,        MRB_ARGS_OPT(1)); /* 15.2.12.5.13 */
-  mrb_define_method(mrb, a, "index",           mrb_ary_index_m,      MRB_ARGS_REQ(1)); /* 15.2.12.5.14 */
-  mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m,    MRB_ARGS_REQ(1)); /* 15.2.12.5.16 */
-  mrb_define_method(mrb, a, "join",            mrb_ary_join_m,       MRB_ARGS_ANY());  /* 15.2.12.5.17 */
-  mrb_define_method(mrb, a, "last",            mrb_ary_last,         MRB_ARGS_ANY());  /* 15.2.12.5.18 */
-  mrb_define_method(mrb, a, "length",          mrb_ary_size,         MRB_ARGS_NONE()); /* 15.2.12.5.19 */
-  mrb_define_method(mrb, a, "pop",             mrb_ary_pop,          MRB_ARGS_NONE()); /* 15.2.12.5.21 */
-  mrb_define_method(mrb, a, "push",            mrb_ary_push_m,       MRB_ARGS_ANY());  /* 15.2.12.5.22 */
-  mrb_define_method(mrb, a, "append",          mrb_ary_push_m,       MRB_ARGS_ANY());
-  mrb_define_method(mrb, a, "replace",         mrb_ary_replace_m,    MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */
-  mrb_define_method(mrb, a, "reverse",         mrb_ary_reverse,      MRB_ARGS_NONE()); /* 15.2.12.5.24 */
-  mrb_define_method(mrb, a, "reverse!",        mrb_ary_reverse_bang, MRB_ARGS_NONE()); /* 15.2.12.5.25 */
-  mrb_define_method(mrb, a, "rindex",          mrb_ary_rindex_m,     MRB_ARGS_REQ(1)); /* 15.2.12.5.26 */
-  mrb_define_method(mrb, a, "shift",           mrb_ary_shift,        MRB_ARGS_NONE()); /* 15.2.12.5.27 */
-  mrb_define_method(mrb, a, "size",            mrb_ary_size,         MRB_ARGS_NONE()); /* 15.2.12.5.28 */
-  mrb_define_method(mrb, a, "slice",           mrb_ary_aget,         MRB_ARGS_ANY());  /* 15.2.12.5.29 */
-  mrb_define_method(mrb, a, "unshift",         mrb_ary_unshift_m,    MRB_ARGS_ANY());  /* 15.2.12.5.30 */
-  mrb_define_method(mrb, a, "prepend",         mrb_ary_unshift_m,    MRB_ARGS_ANY());
+  mrb_define_class_method(mrb, a, "[]",        mrb_ary_s_create,     MRB_ARGS_ANY());    /* 15.2.12.4.1 */
+
+  mrb_define_method(mrb, a, "+",               mrb_ary_plus,         MRB_ARGS_REQ(1));   /* 15.2.12.5.1  */
+  mrb_define_method(mrb, a, "*",               mrb_ary_times,        MRB_ARGS_REQ(1));   /* 15.2.12.5.2  */
+  mrb_define_method(mrb, a, "<<",              mrb_ary_push_m,       MRB_ARGS_REQ(1));   /* 15.2.12.5.3  */
+  mrb_define_method(mrb, a, "[]",              mrb_ary_aget,         MRB_ARGS_ARG(1,1)); /* 15.2.12.5.4  */
+  mrb_define_method(mrb, a, "[]=",             mrb_ary_aset,         MRB_ARGS_ARG(2,1)); /* 15.2.12.5.5  */
+  mrb_define_method(mrb, a, "clear",           mrb_ary_clear_m,      MRB_ARGS_NONE());   /* 15.2.12.5.6  */
+  mrb_define_method(mrb, a, "concat",          mrb_ary_concat_m,     MRB_ARGS_REQ(1));   /* 15.2.12.5.8  */
+  mrb_define_method(mrb, a, "delete_at",       mrb_ary_delete_at,    MRB_ARGS_REQ(1));   /* 15.2.12.5.9  */
+  mrb_define_method(mrb, a, "empty?",          mrb_ary_empty_p,      MRB_ARGS_NONE());   /* 15.2.12.5.12 */
+  mrb_define_method(mrb, a, "first",           mrb_ary_first,        MRB_ARGS_OPT(1));   /* 15.2.12.5.13 */
+  mrb_define_method(mrb, a, "index",           mrb_ary_index_m,      MRB_ARGS_REQ(1));   /* 15.2.12.5.14 */
+  mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m,    MRB_ARGS_REQ(1));   /* 15.2.12.5.16 */
+  mrb_define_method(mrb, a, "join",            mrb_ary_join_m,       MRB_ARGS_OPT(1));   /* 15.2.12.5.17 */
+  mrb_define_method(mrb, a, "last",            mrb_ary_last,         MRB_ARGS_OPT(1));   /* 15.2.12.5.18 */
+  mrb_define_method(mrb, a, "length",          mrb_ary_size,         MRB_ARGS_NONE());   /* 15.2.12.5.19 */
+  mrb_define_method(mrb, a, "pop",             mrb_ary_pop,          MRB_ARGS_NONE());   /* 15.2.12.5.21 */
+  mrb_define_method(mrb, a, "push",            mrb_ary_push_m,       MRB_ARGS_ANY());    /* 15.2.12.5.22 */
+  mrb_define_method(mrb, a, "replace",         mrb_ary_replace_m,    MRB_ARGS_REQ(1));   /* 15.2.12.5.23 */
+  mrb_define_method(mrb, a, "reverse",         mrb_ary_reverse,      MRB_ARGS_NONE());   /* 15.2.12.5.24 */
+  mrb_define_method(mrb, a, "reverse!",        mrb_ary_reverse_bang, MRB_ARGS_NONE());   /* 15.2.12.5.25 */
+  mrb_define_method(mrb, a, "rindex",          mrb_ary_rindex_m,     MRB_ARGS_REQ(1));   /* 15.2.12.5.26 */
+  mrb_define_method(mrb, a, "shift",           mrb_ary_shift,        MRB_ARGS_NONE());   /* 15.2.12.5.27 */
+  mrb_define_method(mrb, a, "size",            mrb_ary_size,         MRB_ARGS_NONE());   /* 15.2.12.5.28 */
+  mrb_define_method(mrb, a, "slice",           mrb_ary_aget,         MRB_ARGS_ARG(1,1)); /* 15.2.12.5.29 */
+  mrb_define_method(mrb, a, "unshift",         mrb_ary_unshift_m,    MRB_ARGS_ANY());    /* 15.2.12.5.30 */
 
   mrb_define_method(mrb, a, "__ary_eq",        mrb_ary_eq,           MRB_ARGS_REQ(1));
   mrb_define_method(mrb, a, "__ary_cmp",       mrb_ary_cmp,          MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, a, "__ary_index",     mrb_ary_index_m,      MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */
+  mrb_define_method(mrb, a, "__ary_index",     mrb_ary_index_m,      MRB_ARGS_REQ(1));   /* kept for mruby-array-ext */
   mrb_define_method(mrb, a, "__svalue",        mrb_ary_svalue,       MRB_ARGS_NONE());
+
+  init_ary_each(mrb, a);
 }
index e4f5a30..591f4ea 100644 (file)
@@ -16,7 +16,7 @@
 #include <mruby/data.h>
 
 struct backtrace_location {
-  int lineno;
+  int32_t lineno;
   mrb_sym method_id;
   const char *filename;
 };
@@ -25,8 +25,11 @@ typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location*
 
 static const mrb_data_type bt_type = { "Backtrace", mrb_free };
 
+mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc);
+mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace);
+
 static void
-each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, mrb_code *pc0, each_backtrace_func func, void *data)
+each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtrace_func func, void *data)
 {
   ptrdiff_t i;
 
@@ -37,7 +40,7 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, mrb_code *pc0, each_backtrace_fu
     struct backtrace_location loc;
     mrb_callinfo *ci;
     mrb_irep *irep;
-    mrb_code *pc;
+    const mrb_code *pc;
 
     ci = &mrb->c->cibase[i];
 
@@ -74,66 +77,27 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, mrb_code *pc0, each_backtrace_fu
 #ifndef MRB_DISABLE_STDIO
 
 static void
-print_backtrace(mrb_state *mrb, mrb_value backtrace)
+print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace)
 {
-  int i;
-  mrb_int n;
+  mrb_int i;
+  mrb_int n = RARRAY_LEN(backtrace);
+  mrb_value *loc, mesg;
   FILE *stream = stderr;
 
-  n = RARRAY_LEN(backtrace) - 1;
-  if (n == 0) return;
-
-  fprintf(stream, "trace (most recent call last):\n");
-  for (i=0; i<n; i++) {
-    mrb_value entry = RARRAY_PTR(backtrace)[n-i-1];
-
-    if (mrb_string_p(entry)) {
-      fprintf(stream, "\t[%d] %.*s\n", i, (int)RSTRING_LEN(entry), RSTRING_PTR(entry));
+  if (n != 0) {
+    fprintf(stream, "trace (most recent call last):\n");
+    for (i=n-1,loc=&RARRAY_PTR(backtrace)[i]; i>0; i--,loc--) {
+      if (mrb_string_p(*loc)) {
+        fprintf(stream, "\t[%d] %.*s\n",
+                (int)i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc));
+      }
     }
-  }
-}
-
-static int
-packed_bt_len(const struct backtrace_location *bt, int n)
-{
-  int len = 0;
-  int i;
-
-  for (i=0; i<n; i++) {
-    if (!bt[i].filename && !bt[i].lineno && !bt[i].method_id)
-      continue;
-    len++;
-  }
-  return len;
-}
-
-static void
-print_packed_backtrace(mrb_state *mrb, mrb_value packed)
-{
-  FILE *stream = stderr;
-  const struct backtrace_location *bt;
-  int n, i;
-  int ai = mrb_gc_arena_save(mrb);
-
-  bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, packed, &bt_type);
-  if (bt == NULL) return;
-  n = (mrb_int)RDATA(packed)->flags;
-
-  if (packed_bt_len(bt, n) == 0) return;
-  fprintf(stream, "trace (most recent call last):\n");
-  for (i = 0; i<n; i++) {
-    const struct backtrace_location *entry = &bt[n-i-1];
-    if (entry->filename == NULL) continue;
-    fprintf(stream, "\t[%d] %s:%d", i, entry->filename, entry->lineno);
-    if (entry->method_id != 0) {
-      const char *method_name;
-
-      method_name = mrb_sym2name(mrb, entry->method_id);
-      fprintf(stream, ":in %s", method_name);
-      mrb_gc_arena_restore(mrb, ai);
+    if (mrb_string_p(*loc)) {
+      fprintf(stream, "%.*s: ", (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc));
     }
-    fprintf(stream, "\n");
   }
+  mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc));
+  fprintf(stream, "%.*s\n", (int)RSTRING_LEN(mesg), RSTRING_PTR(mesg));
 }
 
 /* mrb_print_backtrace
@@ -152,12 +116,8 @@ mrb_print_backtrace(mrb_state *mrb)
 
   backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace"));
   if (mrb_nil_p(backtrace)) return;
-  if (mrb_array_p(backtrace)) {
-    print_backtrace(mrb, backtrace);
-  }
-  else {
-    print_packed_backtrace(mrb, backtrace);
-  }
+  if (!mrb_array_p(backtrace)) backtrace = mrb_unpack_backtrace(mrb, backtrace);
+  print_backtrace(mrb, mrb->exc, backtrace);
 }
 #else
 
@@ -175,7 +135,6 @@ count_backtrace_i(mrb_state *mrb,
 {
   int *lenp = (int*)data;
 
-  if (loc->filename == NULL) return;
   (*lenp)++;
 }
 
@@ -187,7 +146,6 @@ pack_backtrace_i(mrb_state *mrb,
   struct backtrace_location **pptr = (struct backtrace_location**)data;
   struct backtrace_location *ptr = *pptr;
 
-  if (loc->filename == NULL) return;
   *ptr = *loc;
   *pptr = ptr+1;
 }
@@ -205,7 +163,7 @@ packed_backtrace(mrb_state *mrb)
   size = len * sizeof(struct backtrace_location);
   ptr = mrb_malloc(mrb, size);
   backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type);
-  backtrace->flags = (unsigned int)len;
+  backtrace->flags = (uint32_t)len;
   each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, &ptr);
   return mrb_obj_value(backtrace);
 }
@@ -245,13 +203,10 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
     const struct backtrace_location *entry = &bt[i];
     mrb_value btline;
 
-    if (entry->filename == NULL) continue;
-    btline = mrb_format(mrb, "%S:%S",
-                              mrb_str_new_cstr(mrb, entry->filename),
-                              mrb_fixnum_value(entry->lineno));
+    btline = mrb_format(mrb, "%s:%d", entry->filename, (int)entry->lineno);
     if (entry->method_id != 0) {
       mrb_str_cat_lit(mrb, btline, ":in ");
-      mrb_str_cat_cstr(mrb, btline, mrb_sym2name(mrb, entry->method_id));
+      mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id));
     }
     mrb_ary_push(mrb, backtrace, btline);
     mrb_gc_arena_restore(mrb, ai);
index 5c5ee9d..1a36c13 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdarg.h>
 #include <mruby.h>
 #include <mruby/array.h>
+#include <mruby/hash.h>
 #include <mruby/class.h>
 #include <mruby/numeric.h>
 #include <mruby/proc.h>
@@ -15,6 +16,7 @@
 #include <mruby/error.h>
 #include <mruby/data.h>
 #include <mruby/istruct.h>
+#include <mruby/opcode.h>
 
 KHASH_DEFINE(mt, mrb_sym, mrb_method_t, TRUE, kh_int_hash_func, kh_int_hash_equal)
 
@@ -66,15 +68,26 @@ mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb
     name = mrb_class_path(mrb, outer);
     if (mrb_nil_p(name)) {      /* unnamed outer class */
       if (outer != mrb->object_class && outer != c) {
-        mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"),
-                       mrb_obj_value(outer));
+        mrb_obj_iv_set_force(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"),
+                             mrb_obj_value(outer));
       }
       return;
     }
-    mrb_str_cat_cstr(mrb, name, "::");
-    mrb_str_cat_cstr(mrb, name, mrb_sym2name(mrb, id));
+    else {
+      mrb_int len;
+      const char *n = mrb_sym_name_len(mrb, id, &len);
+
+      mrb_str_cat_lit(mrb, name, "::");
+      mrb_str_cat(mrb, name, n, len);
+    }
   }
-  mrb_obj_iv_set(mrb, (struct RObject*)c, nsym, name);
+  mrb_obj_iv_set_force(mrb, (struct RObject*)c, nsym, name);
+}
+
+mrb_bool
+mrb_const_name_p(mrb_state *mrb, const char *name, mrb_int len)
+{
+  return len > 0 && ISUPPER(name[0]) && mrb_ident_p(name+1, len-1);
 }
 
 static void
@@ -120,6 +133,7 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o)
   mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc);
   mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)o);
   mrb_obj_iv_set(mrb, (struct RObject*)sc, mrb_intern_lit(mrb, "__attached__"), mrb_obj_value(o));
+  sc->flags |= o->flags & MRB_FL_OBJ_IS_FROZEN;
 }
 
 static mrb_value
@@ -129,7 +143,7 @@ class_name_str(mrb_state *mrb, struct RClass* c)
   if (mrb_nil_p(path)) {
     path = c->tt == MRB_TT_MODULE ? mrb_str_new_lit(mrb, "#<Module:") :
                                     mrb_str_new_lit(mrb, "#<Class:");
-    mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c));
+    mrb_str_cat_str(mrb, path, mrb_ptr_to_str(mrb, c));
     mrb_str_cat_lit(mrb, path, ">");
   }
   return path;
@@ -170,7 +184,7 @@ static void
 check_if_class_or_module(mrb_state *mrb, mrb_value obj)
 {
   if (!class_ptr_p(obj)) {
-    mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", mrb_inspect(mrb, obj));
+    mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class/module", obj);
   }
 }
 
@@ -200,15 +214,15 @@ mrb_define_module(mrb_state *mrb, const char *name)
   return define_module(mrb, mrb_intern_cstr(mrb, name), mrb->object_class);
 }
 
-MRB_API struct RClass*
+struct RClass*
 mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id)
 {
   check_if_class_or_module(mrb, outer);
   if (mrb_const_defined_at(mrb, outer, id)) {
     mrb_value old = mrb_const_get(mrb, outer, id);
 
-    if (mrb_type(old) != MRB_TT_MODULE) {
-      mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a module", mrb_inspect(mrb, old));
+    if (!mrb_module_p(old)) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a module", old);
     }
     return mrb_class_ptr(old);
   }
@@ -241,9 +255,8 @@ define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *
     c = class_from_sym(mrb, outer, name);
     MRB_CLASS_ORIGIN(c);
     if (super && mrb_class_real(c->super) != super) {
-      mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)",
-                 mrb_sym2str(mrb, name),
-                 mrb_obj_value(c->super), mrb_obj_value(super));
+      mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %n (%C not %C)",
+                 name, c->super, super);
     }
     return c;
   }
@@ -258,7 +271,7 @@ MRB_API struct RClass*
 mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super)
 {
   if (!super) {
-    mrb_warn(mrb, "no super class for '%S', Object assumed", mrb_sym2str(mrb, name));
+    mrb_warn(mrb, "no super class for '%n', Object assumed", name);
   }
   return define_class(mrb, name, super, mrb->object_class);
 }
@@ -272,11 +285,9 @@ mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
 static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value);
 #ifdef MRB_METHOD_CACHE
 static void mc_clear_all(mrb_state *mrb);
-static void mc_clear_by_class(mrb_state *mrb, struct RClass*);
 static void mc_clear_by_id(mrb_state *mrb, struct RClass*, mrb_sym);
 #else
 #define mc_clear_all(mrb)
-#define mc_clear_by_class(mrb,c)
 #define mc_clear_by_id(mrb,c,s)
 #endif
 
@@ -290,7 +301,7 @@ mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass)
     super = mrb->object_class;
   super->flags |= MRB_FL_CLASS_IS_INHERITED;
   s = mrb_obj_value(super);
-  mc_clear_by_class(mrb, klass);
+  mrb_mc_clear_by_class(mrb, klass);
   mid = mrb_intern_lit(mrb, "inherited");
   if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) {
     mrb_value c = mrb_obj_value(klass);
@@ -298,16 +309,15 @@ mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass)
   }
 }
 
-MRB_API struct RClass*
+struct RClass*
 mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
 {
   struct RClass *s;
   struct RClass *c;
 
   if (!mrb_nil_p(super)) {
-    if (mrb_type(super) != MRB_TT_CLASS) {
-      mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)",
-                 mrb_inspect(mrb, super));
+    if (!mrb_class_p(super)) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%!v given)", super);
     }
     s = mrb_class_ptr(super);
   }
@@ -318,14 +328,14 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id
   if (mrb_const_defined_at(mrb, outer, id)) {
     mrb_value old = mrb_const_get(mrb, outer, id);
 
-    if (mrb_type(old) != MRB_TT_CLASS) {
-      mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class", mrb_inspect(mrb, old));
+    if (!mrb_class_p(old)) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class", old);
     }
     c = mrb_class_ptr(old);
     if (s) {
       /* check super class */
       if (mrb_class_real(c->super) != s) {
-        mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %S", old);
+        mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %v", old);
       }
     }
     return c;
@@ -375,7 +385,7 @@ mrb_exc_get(mrb_state *mrb, const char *name)
   mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class),
                               mrb_intern_cstr(mrb, name));
 
-  if (mrb_type(c) != MRB_TT_CLASS) {
+  if (!mrb_class_p(c)) {
     mrb_raise(mrb, mrb->eException_class, "exception corrupted");
   }
   exc = e = mrb_class_ptr(c);
@@ -403,7 +413,7 @@ mrb_module_get(mrb_state *mrb, const char *name)
 /*!
  * Defines a class under the namespace of \a outer.
  * \param outer  a class which contains the new class.
- * \param id     name of the new class
+ * \param name     name of the new class
  * \param super  a class from which the new class will derive.
  *               NULL means \c Object class.
  * \return the created class
@@ -424,8 +434,7 @@ mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, s
 
 #if 0
   if (!super) {
-    mrb_warn(mrb, "no super class for '%S::%S', Object assumed",
-             mrb_obj_value(outer), mrb_sym2str(mrb, id));
+    mrb_warn(mrb, "no super class for '%C::%n', Object assumed", outer, id);
   }
 #endif
   c = define_class(mrb, id, super, outer);
@@ -441,12 +450,7 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_
   MRB_CLASS_ORIGIN(c);
   h = c->mt;
 
-  if (MRB_FROZEN_P(c)) {
-    if (c->tt == MRB_TT_MODULE)
-      mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen module");
-    else
-      mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen class");
-  }
+  mrb_check_frozen(mrb, c);
   if (!h) h = c->mt = kh_init(mt, mrb);
   k = kh_put(mt, mrb, h, mid);
   kh_value(h, k) = m;
@@ -470,6 +474,9 @@ mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t f
   int ai = mrb_gc_arena_save(mrb);
 
   MRB_METHOD_FROM_FUNC(m, func);
+  if (aspec == MRB_ARGS_NONE()) {
+    MRB_METHOD_NOARG_SET(m);
+  }
   mrb_define_method_raw(mrb, c, mid, m);
   mrb_gc_arena_restore(mrb, ai);
 }
@@ -487,8 +494,7 @@ mrb_notimplement(mrb_state *mrb)
   mrb_callinfo *ci = mrb->c->ci;
 
   if (ci->mid) {
-    mrb_value str = mrb_sym2str(mrb, ci->mid);
-    mrb_raisef(mrb, E_NOTIMP_ERROR, "%S() function is unimplemented on this machine", str);
+    mrb_raisef(mrb, E_NOTIMP_ERROR, "%n() function is unimplemented on this machine", ci->mid);
   }
 }
 
@@ -501,30 +507,17 @@ mrb_notimplement_m(mrb_state *mrb, mrb_value self)
   return mrb_nil_value();
 }
 
-#define CHECK_TYPE(mrb, val, t, c) do { \
-  if (mrb_type(val) != (t)) {\
-    mrb_raisef(mrb, E_TYPE_ERROR, "expected %S", mrb_str_new_lit(mrb, c));\
-  }\
-} while (0)
-
-static mrb_value
-to_str(mrb_state *mrb, mrb_value val)
-{
-  CHECK_TYPE(mrb, val, MRB_TT_STRING, "String");
-  return val;
-}
-
 static mrb_value
 to_ary(mrb_state *mrb, mrb_value val)
 {
-  CHECK_TYPE(mrb, val, MRB_TT_ARRAY, "Array");
+  mrb_check_type(mrb, val, MRB_TT_ARRAY);
   return val;
 }
 
 static mrb_value
 to_hash(mrb_state *mrb, mrb_value val)
 {
-  CHECK_TYPE(mrb, val, MRB_TT_HASH, "Hash");
+  mrb_check_type(mrb, val, MRB_TT_HASH);
   return val;
 }
 
@@ -547,18 +540,34 @@ MRB_API mrb_value*
 mrb_get_argv(mrb_state *mrb)
 {
   mrb_int argc = mrb->c->ci->argc;
-  mrb_value *array_argv;
+  mrb_value *array_argv = mrb->c->stack + 1;
   if (argc < 0) {
-    struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]);
+    struct RArray *a = mrb_ary_ptr(*array_argv);
 
     array_argv = ARY_PTR(a);
   }
-  else {
-    array_argv = NULL;
-  }
   return array_argv;
 }
 
+MRB_API mrb_value
+mrb_get_arg1(mrb_state *mrb)
+{
+  mrb_int argc = mrb->c->ci->argc;
+  mrb_value *array_argv = mrb->c->stack + 1;
+  if (argc < 0) {
+    struct RArray *a = mrb_ary_ptr(*array_argv);
+
+    argc = ARY_LEN(a);
+    array_argv = ARY_PTR(a);
+  }
+  if (argc != 1) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
+  }
+  return array_argv[0];
+}
+
+void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
+
 /*
   retrieve arguments from mrb_state.
 
@@ -571,23 +580,24 @@ mrb_get_argv(mrb_state *mrb)
     string  mruby type     C type                 note
     ----------------------------------------------------------------------------------------------
     o:      Object         [mrb_value]
-    C:      class/module   [mrb_value]
+    C:      Class/Module   [mrb_value]
     S:      String         [mrb_value]            when ! follows, the value may be nil
     A:      Array          [mrb_value]            when ! follows, the value may be nil
     H:      Hash           [mrb_value]            when ! follows, the value may be nil
     s:      String         [char*,mrb_int]        Receive two arguments; s! gives (NULL,0) for nil
     z:      String         [char*]                NUL terminated string; z! gives NULL for nil
     a:      Array          [mrb_value*,mrb_int]   Receive two arguments; a! gives (NULL,0) for nil
-    f:      Float          [mrb_float]
-    i:      Integer        [mrb_int]
-    b:      Boolean        [mrb_bool]
-    n:      Symbol         [mrb_sym]
-    d:      Data           [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified
-    I:      Inline struct  [void*]
-    &:      Block          [mrb_value]            &! raises exception if no block given
+    f:      Fixnum/Float   [mrb_float]
+    i:      Fixnum/Float   [mrb_int]
+    b:      boolean        [mrb_bool]
+    n:      String/Symbol  [mrb_sym]
+    d:      data           [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified; when ! follows, the value may be nil
+    I:      inline struct  [void*]
+    &:      block          [mrb_value]            &! raises exception if no block given
     *:      rest argument  [mrb_value*,mrb_int]   The rest of the arguments as an array; *! avoid copy of the stack
     |:      optional                              Following arguments are optional
     ?:      optional given [mrb_bool]             true if preceding argument (optional) is given
+    ':':    keyword args   [mrb_kwargs const]     Get keyword arguments
  */
 MRB_API mrb_int
 mrb_get_args(mrb_state *mrb, const char *format, ...)
@@ -596,17 +606,24 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
   char c;
   mrb_int i = 0;
   va_list ap;
-  mrb_int argc = mrb_get_argc(mrb);
-  mrb_int arg_i = 0;
-  mrb_value *array_argv = mrb_get_argv(mrb);
+  mrb_int argc = mrb->c->ci->argc;
+  mrb_value *array_argv = mrb->c->stack+1;
+  mrb_bool argv_on_stack = argc >= 0;
   mrb_bool opt = FALSE;
   mrb_bool opt_skip = TRUE;
   mrb_bool given = TRUE;
+  mrb_value kdict;
+  mrb_bool reqkarg = FALSE;
+  mrb_int needargc = 0;
 
+  if (!argv_on_stack) {
+    struct RArray *a = mrb_ary_ptr(*array_argv);
+    array_argv = ARY_PTR(a);
+    argc = ARY_LEN(a);
+  }
   va_start(ap, format);
 
-#define ARGV \
-  (array_argv ? array_argv : (mrb->c->stack + 1))
+#define ARGV array_argv
 
   while ((c = *fmt++)) {
     switch (c) {
@@ -615,23 +632,39 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
       break;
     case '*':
       opt_skip = FALSE;
+      if (!reqkarg) reqkarg = strchr(fmt, ':') ? TRUE : FALSE;
       goto check_exit;
     case '!':
       break;
+    case ':':
+      reqkarg = TRUE;
+      /* fall through */
     case '&': case '?':
       if (opt) opt_skip = FALSE;
       break;
     default:
+      if (!opt) needargc ++;
       break;
     }
   }
 
  check_exit:
+  if (reqkarg && argc > needargc && mrb_hash_p(kdict = ARGV[argc - 1])) {
+    mrb_hash_check_kdict(mrb, kdict);
+    argc --;
+  }
+  else {
+    kdict = mrb_nil_value();
+  }
+
   opt = FALSE;
   i = 0;
   while ((c = *format++)) {
+    mrb_value *argv = ARGV;
+    mrb_bool altmode;
+
     switch (c) {
-    case '|': case '*': case '&': case '?':
+    case '|': case '*': case '&': case '?': case ':':
       break;
     default:
       if (argc <= i) {
@@ -645,6 +678,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
       break;
     }
 
+    if (*format == '!') {
+      format ++;
+      altmode = TRUE;
+    }
+    else {
+      altmode = FALSE;
+    }
+
     switch (c) {
     case 'o':
       {
@@ -652,8 +693,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
 
         p = va_arg(ap, mrb_value*);
         if (i < argc) {
-          *p = ARGV[arg_i++];
-          i++;
+          *p = argv[i++];
         }
       }
       break;
@@ -665,12 +705,11 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
         if (i < argc) {
           mrb_value ss;
 
-          ss = ARGV[arg_i++];
+          ss = argv[i++];
           if (!class_ptr_p(ss)) {
-            mrb_raisef(mrb, E_TYPE_ERROR, "%S is not class/module", ss);
+            mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", ss);
           }
           *p = ss;
-          i++;
         }
       }
       break;
@@ -679,17 +718,11 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
         mrb_value *p;
 
         p = va_arg(ap, mrb_value*);
-        if (*format == '!') {
-          format++;
-          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
-            *p = ARGV[arg_i++];
-            i++;
-            break;
-          }
-        }
         if (i < argc) {
-          *p = to_str(mrb, ARGV[arg_i++]);
-          i++;
+          *p = argv[i++];
+          if (!(altmode && mrb_nil_p(*p))) {
+            mrb_to_str(mrb, *p);
+          }
         }
       }
       break;
@@ -698,17 +731,11 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
         mrb_value *p;
 
         p = va_arg(ap, mrb_value*);
-        if (*format == '!') {
-          format++;
-          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
-            *p = ARGV[arg_i++];
-            i++;
-            break;
-          }
-        }
         if (i < argc) {
-          *p = to_ary(mrb, ARGV[arg_i++]);
-          i++;
+          *p = argv[i++];
+          if (!(altmode && mrb_nil_p(*p))) {
+            *p = to_ary(mrb, *p);
+          }
         }
       }
       break;
@@ -717,17 +744,11 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
         mrb_value *p;
 
         p = va_arg(ap, mrb_value*);
-        if (*format == '!') {
-          format++;
-          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
-            *p = ARGV[arg_i++];
-            i++;
-            break;
-          }
-        }
         if (i < argc) {
-          *p = to_hash(mrb, ARGV[arg_i++]);
-          i++;
+          *p = argv[i++];
+          if (!(altmode && mrb_nil_p(*p))) {
+            *p = to_hash(mrb, *p);
+          }
         }
       }
       break;
@@ -739,20 +760,17 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
 
         ps = va_arg(ap, char**);
         pl = va_arg(ap, mrb_int*);
-        if (*format == '!') {
-          format++;
-          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+        if (i < argc) {
+          ss = argv[i++];
+          if (altmode && mrb_nil_p(ss)) {
             *ps = NULL;
             *pl = 0;
-            i++; arg_i++;
-            break;
           }
-        }
-        if (i < argc) {
-          ss = to_str(mrb, ARGV[arg_i++]);
-          *ps = RSTRING_PTR(ss);
-          *pl = RSTRING_LEN(ss);
-          i++;
+          else {
+            mrb_to_str(mrb, ss);
+            *ps = RSTRING_PTR(ss);
+            *pl = RSTRING_LEN(ss);
+          }
         }
       }
       break;
@@ -762,18 +780,15 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
         const char **ps;
 
         ps = va_arg(ap, const char**);
-        if (*format == '!') {
-          format++;
-          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+        if (i < argc) {
+          ss = argv[i++];
+          if (altmode && mrb_nil_p(ss)) {
             *ps = NULL;
-            i++; arg_i++;
-            break;
           }
-        }
-        if (i < argc) {
-          ss = to_str(mrb, ARGV[arg_i++]);
-          *ps = mrb_string_value_cstr(mrb, &ss);
-          i++;
+          else {
+            mrb_to_str(mrb, ss);
+            *ps = RSTRING_CSTR(mrb, ss);
+          }
         }
       }
       break;
@@ -786,21 +801,18 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
 
         pb = va_arg(ap, mrb_value**);
         pl = va_arg(ap, mrb_int*);
-        if (*format == '!') {
-          format++;
-          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+        if (i < argc) {
+          aa = argv[i++];
+          if (altmode && mrb_nil_p(aa)) {
             *pb = 0;
             *pl = 0;
-            i++; arg_i++;
-            break;
           }
-        }
-        if (i < argc) {
-          aa = to_ary(mrb, ARGV[arg_i++]);
-          a = mrb_ary_ptr(aa);
-          *pb = ARY_PTR(a);
-          *pl = ARY_LEN(a);
-          i++;
+          else {
+            aa = to_ary(mrb, aa);
+            a = mrb_ary_ptr(aa);
+            *pb = ARY_PTR(a);
+            *pl = ARY_LEN(a);
+          }
         }
       }
       break;
@@ -811,14 +823,12 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
 
         p = va_arg(ap, void**);
         if (i < argc) {
-          ss = ARGV[arg_i];
-          if (mrb_type(ss) != MRB_TT_ISTRUCT)
+          ss = argv[i++];
+          if (!mrb_istruct_p(ss))
           {
-            mrb_raisef(mrb, E_TYPE_ERROR, "%S is not inline struct", ss);
+            mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", ss);
           }
           *p = mrb_istruct_ptr(ss);
-          arg_i++;
-          i++;
         }
       }
       break;
@@ -829,9 +839,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
 
         p = va_arg(ap, mrb_float*);
         if (i < argc) {
-          *p = mrb_to_flo(mrb, ARGV[arg_i]);
-          arg_i++;
-          i++;
+          *p = mrb_to_flo(mrb, argv[i++]);
         }
       }
       break;
@@ -842,31 +850,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
 
         p = va_arg(ap, mrb_int*);
         if (i < argc) {
-          switch (mrb_type(ARGV[arg_i])) {
-            case MRB_TT_FIXNUM:
-              *p = mrb_fixnum(ARGV[arg_i]);
-              break;
-#ifndef MRB_WITHOUT_FLOAT
-            case MRB_TT_FLOAT:
-              {
-                mrb_float f = mrb_float(ARGV[arg_i]);
-
-                if (!FIXABLE_FLOAT(f)) {
-                  mrb_raise(mrb, E_RANGE_ERROR, "float too big for int");
-                }
-                *p = (mrb_int)f;
-              }
-              break;
-#endif
-            case MRB_TT_STRING:
-              mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer");
-              break;
-            default:
-              *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i]));
-              break;
-          }
-          arg_i++;
-          i++;
+          *p = mrb_fixnum(mrb_to_int(mrb, argv[i++]));
         }
       }
       break;
@@ -875,9 +859,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
         mrb_bool *boolp = va_arg(ap, mrb_bool*);
 
         if (i < argc) {
-          mrb_value b = ARGV[arg_i++];
+          mrb_value b = argv[i++];
           *boolp = mrb_test(b);
-          i++;
         }
       }
       break;
@@ -889,9 +872,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
         if (i < argc) {
           mrb_value ss;
 
-          ss = ARGV[arg_i++];
+          ss = argv[i++];
           *symp = to_sym(mrb, ss);
-          i++;
         }
       }
       break;
@@ -902,17 +884,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
 
         datap = va_arg(ap, void**);
         type = va_arg(ap, struct mrb_data_type const*);
-        if (*format == '!') {
-          format++;
-          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+        if (i < argc) {
+          mrb_value dd = argv[i++];
+          if (altmode && mrb_nil_p(dd)) {
             *datap = 0;
-            i++; arg_i++;
-            break;
           }
-        }
-        if (i < argc) {
-          *datap = mrb_data_get_ptr(mrb, ARGV[arg_i++], type);
-          ++i;
+          else {
+            *datap = mrb_data_get_ptr(mrb, dd, type);
+          }
         }
       }
       break;
@@ -928,17 +907,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
         else {
           bp = mrb->c->stack + mrb->c->ci->argc + 1;
         }
-        if (*format == '!') {
-          format ++;
-          if (mrb_nil_p(*bp)) {
-            mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
-          }
+        if (altmode && mrb_nil_p(*bp)) {
+          mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
         }
         *p = *bp;
       }
       break;
     case '|':
-      if (opt_skip && i == argc) return argc;
+      if (opt_skip && i == argc) goto finish;
       opt = TRUE;
       break;
     case '?':
@@ -954,28 +930,23 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
       {
         mrb_value **var;
         mrb_int *pl;
-        mrb_bool nocopy = array_argv ? TRUE : FALSE;
+        mrb_bool nocopy = (altmode || !argv_on_stack) ? TRUE : FALSE;
 
-        if (*format == '!') {
-          format++;
-          nocopy = TRUE;
-        }
         var = va_arg(ap, mrb_value**);
         pl = va_arg(ap, mrb_int*);
         if (argc > i) {
           *pl = argc-i;
           if (*pl > 0) {
             if (nocopy) {
-              *var = ARGV+arg_i;
+              *var = argv+i;
             }
             else {
-              mrb_value args = mrb_ary_new_from_values(mrb, *pl, ARGV+arg_i);
+              mrb_value args = mrb_ary_new_from_values(mrb, *pl, argv+i);
               RARRAY(args)->c = NULL;
               *var = RARRAY_PTR(args);
             }
           }
           i = argc;
-          arg_i += *pl;
         }
         else {
           *pl = 0;
@@ -983,8 +954,64 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
         }
       }
       break;
+
+    case ':':
+      {
+        mrb_value ksrc = mrb_hash_p(kdict) ? mrb_hash_dup(mrb, kdict) : mrb_hash_new(mrb);
+        const mrb_kwargs *kwargs = va_arg(ap, const mrb_kwargs*);
+        mrb_value *rest;
+
+        if (kwargs == NULL) {
+          rest = NULL;
+        }
+        else {
+          uint32_t kwnum = kwargs->num;
+          uint32_t required = kwargs->required;
+          const char *const *kname = kwargs->table;
+          mrb_value *values = kwargs->values;
+          uint32_t j;
+          const uint32_t keyword_max = 40;
+
+          if (kwnum > keyword_max || required > kwnum) {
+            mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword number is too large");
+          }
+
+          for (j = required; j > 0; j --, kname ++, values ++) {
+            mrb_value k = mrb_symbol_value(mrb_intern_cstr(mrb, *kname));
+            if (!mrb_hash_key_p(mrb, ksrc, k)) {
+              mrb_raisef(mrb, E_ARGUMENT_ERROR, "missing keyword: %s", *kname);
+            }
+            *values = mrb_hash_delete_key(mrb, ksrc, k);
+            mrb_gc_protect(mrb, *values);
+          }
+
+          for (j = kwnum - required; j > 0; j --, kname ++, values ++) {
+            mrb_value k = mrb_symbol_value(mrb_intern_cstr(mrb, *kname));
+            if (mrb_hash_key_p(mrb, ksrc, k)) {
+              *values = mrb_hash_delete_key(mrb, ksrc, k);
+              mrb_gc_protect(mrb, *values);
+            }
+            else {
+              *values = mrb_undef_value();
+            }
+          }
+
+          rest = kwargs->rest;
+        }
+
+        if (rest) {
+          *rest = ksrc;
+        }
+        else if (!mrb_hash_empty_p(mrb, ksrc)) {
+          ksrc = mrb_hash_keys(mrb, ksrc);
+          ksrc = RARRAY_PTR(ksrc)[0];
+          mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown keyword: %v", ksrc);
+        }
+      }
+      break;
+
     default:
-      mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %S", mrb_str_new(mrb, &c, 1));
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %c", c);
       break;
     }
   }
@@ -994,6 +1021,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
   if (!c && argc > i) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
   }
+
+finish:
   va_end(ap);
   return i;
 }
@@ -1078,7 +1107,7 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, stru
     m->flags |= MRB_FL_CLASS_IS_INHERITED;
     ins_pos->super = ic;
     mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic);
-    mc_clear_by_class(mrb, ins_pos);
+    mrb_mc_clear_by_class(mrb, ins_pos);
     ins_pos = ic;
   skip:
     m = m->super;
@@ -1090,8 +1119,8 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, stru
 MRB_API void
 mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
 {
-  int changed = include_module_at(mrb, c, find_origin(c), m, 1);
-  if (changed < 0) {
+  mrb_check_frozen(mrb, c);
+  if (include_module_at(mrb, c, find_origin(c), m, 1) < 0) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected");
   }
 }
@@ -1102,6 +1131,7 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
   struct RClass *origin;
   int changed = 0;
 
+  mrb_check_frozen(mrb, c);
   if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
     origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c);
     origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED;
@@ -1199,10 +1229,9 @@ mrb_mod_ancestors(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_mod_extend_object(mrb_state *mrb, mrb_value mod)
 {
-  mrb_value obj;
+  mrb_value obj = mrb_get_arg1(mrb);
 
   mrb_check_type(mrb, mod, MRB_TT_MODULE);
-  mrb_get_args(mrb, "o", &obj);
   mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod));
   return mod;
 }
@@ -1229,33 +1258,45 @@ mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod)
   return mod;
 }
 
-MRB_API mrb_value
-mrb_singleton_class(mrb_state *mrb, mrb_value v)
+/* returns mrb_class_ptr(mrb_singleton_class()) */
+/* except that it return NULL for immediate values */
+MRB_API struct RClass*
+mrb_singleton_class_ptr(mrb_state *mrb, mrb_value v)
 {
   struct RBasic *obj;
 
   switch (mrb_type(v)) {
   case MRB_TT_FALSE:
     if (mrb_nil_p(v))
-      return mrb_obj_value(mrb->nil_class);
-    return mrb_obj_value(mrb->false_class);
+      return mrb->nil_class;
+    return mrb->false_class;
   case MRB_TT_TRUE:
-    return mrb_obj_value(mrb->true_class);
+    return mrb->true_class;
   case MRB_TT_CPTR:
-    return mrb_obj_value(mrb->object_class);
+    return mrb->object_class;
   case MRB_TT_SYMBOL:
   case MRB_TT_FIXNUM:
 #ifndef MRB_WITHOUT_FLOAT
   case MRB_TT_FLOAT:
 #endif
-    mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
-    return mrb_nil_value();    /* not reached */
+    return NULL;
   default:
     break;
   }
   obj = mrb_basic_ptr(v);
   prepare_singleton_class(mrb, obj);
-  return mrb_obj_value(obj->c);
+  return obj->c;
+}
+
+MRB_API mrb_value
+mrb_singleton_class(mrb_state *mrb, mrb_value v)
+{
+  struct RClass *c = mrb_singleton_class_ptr(mrb, v);
+
+  if (c == NULL) {
+    mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
+  }
+  return mrb_obj_value(c);
 }
 
 MRB_API void
@@ -1290,8 +1331,8 @@ mc_clear_all(mrb_state *mrb)
   }
 }
 
-static void
-mc_clear_by_class(mrb_state *mrb, struct RClass *c)
+void
+mrb_mc_clear_by_class(mrb_state *mrb, struct RClass *c)
 {
   struct mrb_cache_entry *mc = mrb->cache;
   int i;
@@ -1372,25 +1413,57 @@ mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
 
   m = mrb_method_search_vm(mrb, &c, mid);
   if (MRB_METHOD_UNDEF_P(m)) {
-    mrb_value inspect = mrb_funcall(mrb, mrb_obj_value(c), "inspect", 0);
-    if (mrb_string_p(inspect) && RSTRING_LEN(inspect) > 64) {
-      inspect = mrb_any_to_s(mrb, mrb_obj_value(c));
-    }
-    mrb_name_error(mrb, mid, "undefined method '%S' for class %S",
-               mrb_sym2str(mrb, mid), inspect);
+    mrb_name_error(mrb, mid, "undefined method '%n' for class %C", mid, c);
   }
   return m;
 }
 
+#define ONSTACK_ALLOC_MAX 32
+
+static mrb_sym
+prepare_name_common(mrb_state *mrb, mrb_sym sym, const char *prefix, const char *suffix)
+{
+  char onstack[ONSTACK_ALLOC_MAX];
+  mrb_int sym_len;
+  const char *sym_str = mrb_sym_name_len(mrb, sym, &sym_len);
+  size_t prefix_len = prefix ? strlen(prefix) : 0;
+  size_t suffix_len = suffix ? strlen(suffix) : 0;
+  size_t name_len = sym_len + prefix_len + suffix_len;
+  char *buf = name_len > sizeof(onstack) ? (char *)mrb_alloca(mrb, name_len) : onstack;
+  char *p = buf;
+
+  if (prefix_len > 0) {
+    memcpy(p, prefix, prefix_len);
+    p += prefix_len;
+  }
+
+  memcpy(p, sym_str, sym_len);
+  p += sym_len;
+
+  if (suffix_len > 0) {
+    memcpy(p, suffix, suffix_len);
+    p += suffix_len;
+  }
+
+  return mrb_intern(mrb, buf, name_len);
+}
+
 static mrb_value
-attr_reader(mrb_state *mrb, mrb_value obj)
+prepare_ivar_name(mrb_state *mrb, mrb_sym sym)
 {
-  mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
-  return mrb_iv_get(mrb, obj, to_sym(mrb, name));
+  sym = prepare_name_common(mrb, sym, "@", NULL);
+  mrb_iv_name_sym_check(mrb, sym);
+  return mrb_symbol_value(sym);
+}
+
+static mrb_sym
+prepare_writer_name(mrb_state *mrb, mrb_sym sym)
+{
+  return prepare_name_common(mrb, sym, NULL, "=");
 }
 
 static mrb_value
-mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
+mod_attr_define(mrb_state *mrb, mrb_value mod, mrb_value (*accessor)(mrb_state *, mrb_value), mrb_sym (*access_name)(mrb_state *, mrb_sym))
 {
   struct RClass *c = mrb_class_ptr(mod);
   mrb_value *argv;
@@ -1400,20 +1473,18 @@ mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
   mrb_get_args(mrb, "*", &argv, &argc);
   ai = mrb_gc_arena_save(mrb);
   for (i=0; i<argc; i++) {
-    mrb_value name, str;
-    mrb_sym method, sym;
+    mrb_value name;
+    mrb_sym method;
     struct RProc *p;
     mrb_method_t m;
 
     method = to_sym(mrb, argv[i]);
-    name = mrb_sym2str(mrb, method);
-    str = mrb_str_new_capa(mrb, RSTRING_LEN(name)+1);
-    mrb_str_cat_lit(mrb, str, "@");
-    mrb_str_cat_str(mrb, str, name);
-    sym = mrb_intern_str(mrb, str);
-    mrb_iv_name_sym_check(mrb, sym);
-    name = mrb_symbol_value(sym);
-    p = mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name);
+    name = prepare_ivar_name(mrb, method);
+    if (access_name) {
+      method = access_name(mrb, method);
+    }
+
+    p = mrb_proc_new_cfunc_with_env(mrb, accessor, 1, &name);
     MRB_METHOD_FROM_PROC(m, p);
     mrb_define_method_raw(mrb, c, method, m);
     mrb_gc_arena_restore(mrb, ai);
@@ -1422,12 +1493,24 @@ mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
 }
 
 static mrb_value
+attr_reader(mrb_state *mrb, mrb_value obj)
+{
+  mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
+  return mrb_iv_get(mrb, obj, to_sym(mrb, name));
+}
+
+static mrb_value
+mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
+{
+  return mod_attr_define(mrb, mod, attr_reader, NULL);
+}
+
+static mrb_value
 attr_writer(mrb_state *mrb, mrb_value obj)
 {
   mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
-  mrb_value val;
+  mrb_value val = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &val);
   mrb_iv_set(mrb, obj, to_sym(mrb, name), val);
   return val;
 }
@@ -1435,42 +1518,7 @@ attr_writer(mrb_state *mrb, mrb_value obj)
 static mrb_value
 mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod)
 {
-  struct RClass *c = mrb_class_ptr(mod);
-  mrb_value *argv;
-  mrb_int argc, i;
-  int ai;
-
-  mrb_get_args(mrb, "*", &argv, &argc);
-  ai = mrb_gc_arena_save(mrb);
-  for (i=0; i<argc; i++) {
-    mrb_value name, str, attr;
-    mrb_sym method, sym;
-    struct RProc *p;
-    mrb_method_t m;
-
-    method = to_sym(mrb, argv[i]);
-
-    /* prepare iv name (@name) */
-    name = mrb_sym2str(mrb, method);
-    str = mrb_str_new_capa(mrb, RSTRING_LEN(name)+1);
-    mrb_str_cat_lit(mrb, str, "@");
-    mrb_str_cat_str(mrb, str, name);
-    sym = mrb_intern_str(mrb, str);
-    mrb_iv_name_sym_check(mrb, sym);
-    attr = mrb_symbol_value(sym);
-
-    /* prepare method name (name=) */
-    str = mrb_str_new_capa(mrb, RSTRING_LEN(str));
-    mrb_str_cat_str(mrb, str, name);
-    mrb_str_cat_lit(mrb, str, "=");
-    method = mrb_intern_str(mrb, str);
-
-    p = mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr);
-    MRB_METHOD_FROM_PROC(m, p);
-    mrb_define_method_raw(mrb, c, method, m);
-    mrb_gc_arena_restore(mrb, ai);
-  }
-  return mrb_nil_value();
+  return mod_attr_define(mrb, mod, attr_writer, prepare_writer_name);
 }
 
 static mrb_value
@@ -1485,7 +1533,7 @@ mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
 
   if (ttype == 0) ttype = MRB_TT_OBJECT;
   if (ttype <= MRB_TT_CPTR) {
-    mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %S", cv);
+    mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %v", cv);
   }
   o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
   return mrb_obj_value(o);
@@ -1503,29 +1551,20 @@ mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
  *
  */
 
-MRB_API mrb_value
+mrb_value
 mrb_instance_new(mrb_state *mrb, mrb_value cv)
 {
   mrb_value obj, blk;
   mrb_value *argv;
   mrb_int argc;
   mrb_sym init;
-  mrb_method_t m;
 
-  mrb_get_args(mrb, "*&", &argv, &argc, &blk);
+  mrb_get_args(mrb, "*!&", &argv, &argc, &blk);
   obj = mrb_instance_alloc(mrb, cv);
   init = mrb_intern_lit(mrb, "initialize");
-  m = mrb_method_search(mrb, mrb_class(mrb, obj), init);
-  if (MRB_METHOD_CFUNC_P(m)) {
-    mrb_func_t f = MRB_METHOD_CFUNC(m);
-    if (f != mrb_bob_init) {
-      f(mrb, obj);
-    }
-  }
-  else {
+  if (!mrb_func_basic_p(mrb, obj, init, mrb_bob_init)) {
     mrb_funcall_with_block(mrb, obj, init, argc, argv, blk);
   }
-
   return obj;
 }
 
@@ -1569,7 +1608,10 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv)
   }
   new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
   mid = mrb_intern_lit(mrb, "initialize");
-  if (!mrb_func_basic_p(mrb, new_class, mid, mrb_bob_init)) {
+  if (mrb_func_basic_p(mrb, new_class, mid, mrb_class_initialize)) {
+    mrb_class_initialize(mrb, new_class);
+  }
+  else {
     mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk);
   }
   mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class));
@@ -1636,21 +1678,11 @@ mrb_bob_not(mrb_state *mrb, mrb_value cv)
 mrb_value
 mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
 {
-  mrb_value arg;
+  mrb_value arg = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &arg);
   return mrb_bool_value(mrb_obj_equal(mrb, self, arg));
 }
 
-static mrb_value
-mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self)
-{
-  mrb_value arg;
-
-  mrb_get_args(mrb, "o", &arg);
-  return mrb_bool_value(!mrb_equal(mrb, self, arg));
-}
-
 MRB_API mrb_bool
 mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid)
 {
@@ -1682,7 +1714,7 @@ mrb_class_path(mrb_state *mrb, struct RClass *c)
   }
   else if (mrb_symbol_p(path)) {
     /* toplevel class/module */
-    return mrb_sym2str(mrb, mrb_symbol(path));
+    return mrb_sym_str(mrb, mrb_symbol(path));
   }
   return mrb_str_dup(mrb, path);
 }
@@ -1701,7 +1733,10 @@ mrb_class_real(struct RClass* cl)
 MRB_API const char*
 mrb_class_name(mrb_state *mrb, struct RClass* c)
 {
-  mrb_value name = class_name_str(mrb, c);
+  mrb_value name;
+
+  if (c == NULL) return NULL;
+  name = class_name_str(mrb, c);
   return RSTRING_PTR(name);
 }
 
@@ -1721,7 +1756,7 @@ static void
 mrb_check_inheritable(mrb_state *mrb, struct RClass *super)
 {
   if (super->tt != MRB_TT_CLASS) {
-    mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", mrb_obj_value(super));
+    mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%C given)", super);
   }
   if (super->tt == MRB_TT_SCLASS) {
     mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class");
@@ -1790,11 +1825,31 @@ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
 {
   mrb_method_t m = mrb_method_search(mrb, c, b);
 
+  if (!MRB_METHOD_CFUNC_P(m)) {
+    struct RProc *p = MRB_METHOD_PROC(m);
+
+    if (MRB_PROC_ENV_P(p)) {
+      MRB_PROC_ENV(p)->mid = b;
+    }
+    else {
+      struct RClass *tc = MRB_PROC_TARGET_CLASS(p);
+      struct REnv *e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL);
+
+      e->mid = b;
+      if (tc) {
+        e->c = tc;
+        mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)tc);
+      }
+      p->e.env = e;
+      p->flags |= MRB_PROC_ENVSET;
+    }
+  }
   mrb_define_method_raw(mrb, c, a, m);
 }
 
 /*!
  * Defines an alias of a method.
+ * \param mrb    the mruby state
  * \param klass  the class which the original method belongs to
  * \param name1  a new name for the method
  * \param name2  the original name of the method
@@ -1818,7 +1873,7 @@ mrb_value
 mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
 {
 
-  if (mrb_type(klass) == MRB_TT_SCLASS) {
+  if (mrb_sclass_p(klass)) {
     mrb_value v = mrb_iv_get(mrb, klass, mrb_intern_lit(mrb, "__attached__"));
     mrb_value str = mrb_str_new_lit(mrb, "#<Class:");
 
@@ -1843,27 +1898,31 @@ mrb_mod_alias(mrb_state *mrb, mrb_value mod)
 
   mrb_get_args(mrb, "nn", &new_name, &old_name);
   mrb_alias_method(mrb, c, new_name, old_name);
-  return mrb_nil_value();
+  return mod;
+}
+
+static void
+undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a)
+{
+  mrb_method_t m;
+
+  MRB_METHOD_FROM_PROC(m, NULL);
+  mrb_define_method_raw(mrb, c, a, m);
 }
 
 void
 mrb_undef_method_id(mrb_state *mrb, struct RClass *c, mrb_sym a)
 {
   if (!mrb_obj_respond_to(mrb, c, a)) {
-    mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c));
-  }
-  else {
-    mrb_method_t m;
-
-    MRB_METHOD_FROM_PROC(m, NULL);
-    mrb_define_method_raw(mrb, c, a, m);
+    mrb_name_error(mrb, a, "undefined method '%n' for class '%C'", a, c);
   }
+  undef_method(mrb, c, a);
 }
 
 MRB_API void
 mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name)
 {
-  mrb_undef_method_id(mrb, c, mrb_intern_cstr(mrb, name));
+  undef_method(mrb, c, mrb_intern_cstr(mrb, name));
 }
 
 MRB_API void
@@ -1887,19 +1946,13 @@ mrb_mod_undef(mrb_state *mrb, mrb_value mod)
   return mrb_nil_value();
 }
 
-static mrb_bool
-const_name_p(mrb_state *mrb, const char *name, mrb_int len)
-{
-  return len > 0 && ISUPPER(name[0]) && mrb_ident_p(name+1, len-1);
-}
-
 static void
 check_const_name_sym(mrb_state *mrb, mrb_sym id)
 {
   mrb_int len;
-  const char *name = mrb_sym2name_len(mrb, id, &len);
-  if (!const_name_p(mrb, name, len)) {
-    mrb_name_error(mrb, id, "wrong constant name %S", mrb_sym2str(mrb, id));
+  const char *name = mrb_sym_name_len(mrb, id, &len);
+  if (!mrb_const_name_p(mrb, name, len)) {
+    mrb_name_error(mrb, id, "wrong constant name %n", id);
   }
 }
 
@@ -1927,13 +1980,11 @@ mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id)
 static mrb_value
 mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
 {
-  mrb_value path;
+  mrb_value path = mrb_get_arg1(mrb);
   mrb_sym id;
   char *ptr;
   mrb_int off, end, len;
 
-  mrb_get_args(mrb, "o", &path);
-
   if (mrb_symbol_p(path)) {
     /* const get with symbol */
     id = mrb_symbol(path);
@@ -1956,7 +2007,7 @@ mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
     else {
       off = end + 2;
       if (off == len) {         /* trailing "::" */
-        mrb_name_error(mrb, id, "wrong constant name '%S'", path);
+        mrb_name_error(mrb, id, "wrong constant name '%v'", path);
       }
     }
   }
@@ -1986,7 +2037,7 @@ mrb_mod_remove_const(mrb_state *mrb, mrb_value mod)
   check_const_name_sym(mrb, id);
   val = mrb_iv_remove(mrb, mod, id);
   if (mrb_undef_p(val)) {
-    mrb_name_error(mrb, id, "constant %S not defined", mrb_sym2str(mrb, id));
+    mrb_name_error(mrb, id, "constant %n not defined", id);
   }
   return val;
 }
@@ -1999,13 +2050,10 @@ mrb_mod_const_missing(mrb_state *mrb, mrb_value mod)
   mrb_get_args(mrb, "n", &sym);
 
   if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) {
-    mrb_name_error(mrb, sym, "uninitialized constant %S::%S",
-                   mod,
-                   mrb_sym2str(mrb, sym));
+    mrb_name_error(mrb, sym, "uninitialized constant %v::%n", mod, sym);
   }
   else {
-    mrb_name_error(mrb, sym, "uninitialized constant %S",
-                   mrb_sym2str(mrb, sym));
+    mrb_name_error(mrb, sym, "uninitialized constant %n", sym);
   }
   /* not reached */
   return mrb_nil_value();
@@ -2066,7 +2114,7 @@ mod_define_method(mrb_state *mrb, mrb_value self)
       /* ignored */
       break;
     default:
-      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected Proc)", mrb_obj_value(mrb_obj_class(mrb, proc)));
+      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %T (expected Proc)", proc);
       break;
   }
   if (mrb_nil_p(blk)) {
@@ -2089,16 +2137,23 @@ top_define_method(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_mod_eqq(mrb_state *mrb, mrb_value mod)
 {
-  mrb_value obj;
+  mrb_value obj = mrb_get_arg1(mrb);
   mrb_bool eqq;
 
-  mrb_get_args(mrb, "o", &obj);
   eqq = mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod));
 
   return mrb_bool_value(eqq);
 }
 
 static mrb_value
+mrb_mod_dup(mrb_state *mrb, mrb_value self)
+{
+  mrb_value mod = mrb_obj_clone(mrb, self);
+  MRB_UNSET_FROZEN_FLAG(mrb_obj_ptr(mod));
+  return mod;
+}
+
+static mrb_value
 mrb_mod_module_function(mrb_state *mrb, mrb_value mod)
 {
   mrb_value *argv;
@@ -2146,6 +2201,40 @@ inspect_main(mrb_state *mrb, mrb_value mod)
   return mrb_str_new_lit(mrb, "main");
 }
 
+static const mrb_code new_iseq[] = {
+  OP_ENTER, 0x0, 0x10, 0x1,  /* OP_ENTER     0:0:1:0:0:0:1 */
+  OP_LOADSELF, 0x3,          /* OP_LOADSELF  R3 */
+  OP_SEND, 0x3, 0x0, 0x0,    /* OP_SEND      R3  :allocate  0 */
+  OP_MOVE, 0x0, 0x3,         /* OP_MOVE      R0  R3 */
+  OP_MOVE, 0x4, 0x1,         /* OP_MOVE      R4  R1 */
+  OP_MOVE, 0x5, 0x2,         /* OP_MOVE      R5  R2 */
+  OP_SENDVB, 0x3, 0x1,       /* OP_SENDVB    R4  :initialize */
+  OP_RETURN, 0x0             /* OP_RETURN    R0 */
+};
+
+static void
+init_class_new(mrb_state *mrb, struct RClass *cls)
+{
+  struct RProc *p;
+  mrb_method_t m;
+  mrb_irep *new_irep = (mrb_irep*)mrb_malloc(mrb, sizeof(mrb_irep));
+  static const mrb_irep mrb_irep_zero = { 0 };
+
+  *new_irep = mrb_irep_zero;
+  new_irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*2);
+  new_irep->syms[0] = mrb_intern_lit(mrb, "allocate");
+  new_irep->syms[1] = mrb_intern_lit(mrb, "initialize");
+  new_irep->slen = 2;
+  new_irep->flags = MRB_ISEQ_NO_FREE;
+  new_irep->iseq = new_iseq;
+  new_irep->ilen = sizeof(new_iseq);
+  new_irep->nregs = 6;
+  new_irep->nlocals = 3;
+  p = mrb_proc_new(mrb, new_irep);
+  MRB_METHOD_FROM_PROC(m, p);
+  mrb_define_method_raw(mrb, cls, mrb_intern_lit(mrb, "new"), m);
+}
+
 void
 mrb_init_class(mrb_state *mrb)
 {
@@ -2168,7 +2257,6 @@ mrb_init_class(mrb_state *mrb)
 
   /* name basic classes */
   mrb_define_const(mrb, bob, "BasicObject", mrb_obj_value(bob));
-  mrb_define_const(mrb, obj, "BasicObject", mrb_obj_value(bob));
   mrb_define_const(mrb, obj, "Object",      mrb_obj_value(obj));
   mrb_define_const(mrb, obj, "Module",      mrb_obj_value(mod));
   mrb_define_const(mrb, obj, "Class",       mrb_obj_value(cls));
@@ -2186,17 +2274,19 @@ mrb_init_class(mrb_state *mrb)
   mrb_define_method(mrb, bob, "initialize",              mrb_bob_init,             MRB_ARGS_NONE());
   mrb_define_method(mrb, bob, "!",                       mrb_bob_not,              MRB_ARGS_NONE());
   mrb_define_method(mrb, bob, "==",                      mrb_obj_equal_m,          MRB_ARGS_REQ(1)); /* 15.3.1.3.1  */
-  mrb_define_method(mrb, bob, "!=",                      mrb_obj_not_equal_m,      MRB_ARGS_REQ(1));
   mrb_define_method(mrb, bob, "__id__",                  mrb_obj_id_m,             MRB_ARGS_NONE()); /* 15.3.1.3.4  */
-  mrb_define_method(mrb, bob, "__send__",                mrb_f_send,               MRB_ARGS_ANY());  /* 15.3.1.3.5  */
-  mrb_define_method(mrb, bob, "instance_eval",           mrb_obj_instance_eval,    MRB_ARGS_ANY());  /* 15.3.1.3.18 */
+  mrb_define_method(mrb, bob, "__send__",                mrb_f_send,               MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK());  /* 15.3.1.3.5  */
+  mrb_define_method(mrb, bob, "equal?",                  mrb_obj_equal_m,          MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */
+  mrb_define_method(mrb, bob, "instance_eval",           mrb_obj_instance_eval,    MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK());  /* 15.3.1.3.18 */
 
-  mrb_define_class_method(mrb, cls, "new",               mrb_class_new_class,      MRB_ARGS_OPT(1));
+  mrb_define_class_method(mrb, cls, "new",               mrb_class_new_class,      MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK());
+  mrb_define_method(mrb, cls, "allocate",                mrb_instance_alloc,       MRB_ARGS_NONE());
   mrb_define_method(mrb, cls, "superclass",              mrb_class_superclass,     MRB_ARGS_NONE()); /* 15.2.3.3.4 */
-  mrb_define_method(mrb, cls, "new",                     mrb_instance_new,         MRB_ARGS_ANY());  /* 15.2.3.3.3 */
   mrb_define_method(mrb, cls, "initialize",              mrb_class_initialize,     MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */
   mrb_define_method(mrb, cls, "inherited",               mrb_bob_init,             MRB_ARGS_REQ(1));
 
+  init_class_new(mrb, cls);
+
   MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE);
   mrb_define_method(mrb, mod, "extend_object",           mrb_mod_extend_object,    MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */
   mrb_define_method(mrb, mod, "extended",                mrb_bob_init,             MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
@@ -2226,10 +2316,13 @@ mrb_init_class(mrb_state *mrb)
   mrb_define_method(mrb, mod, "const_missing",           mrb_mod_const_missing,    MRB_ARGS_REQ(1));
   mrb_define_method(mrb, mod, "method_defined?",         mrb_mod_method_defined,   MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
   mrb_define_method(mrb, mod, "define_method",           mod_define_method,        MRB_ARGS_ARG(1,1));
-  mrb_define_method(mrb, mod, "===",                     mrb_mod_eqq,              MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, mod, "===",                     mrb_mod_eqq,              MRB_ARGS_REQ(1)); /* 15.2.2.4.7 */
+  mrb_define_method(mrb, mod, "dup",                     mrb_mod_dup,              MRB_ARGS_NONE());
 
   mrb_undef_method(mrb, cls, "append_features");
+  mrb_undef_method(mrb, cls, "prepend_features");
   mrb_undef_method(mrb, cls, "extend_object");
+  mrb_undef_method(mrb, cls, "module_function");
 
   mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
   mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());
index 5bffefd..649be17 100644 (file)
@@ -16,7 +16,7 @@ print_r(mrb_state *mrb, mrb_irep *irep, size_t n)
   for (i=0; i+1<irep->nlocals; i++) {
     if (irep->lv[i].r == n) {
       mrb_sym sym = irep->lv[i].name;
-      printf(" R%d:%s", (int)n, mrb_sym2name(mrb, sym));
+      printf(" R%d:%s", (int)n, mrb_sym_dump(mrb, sym));
       break;
     }
   }
@@ -69,7 +69,7 @@ static void
 codedump(mrb_state *mrb, mrb_irep *irep)
 {
   int ai;
-  mrb_code *pc, *pcend;
+  const mrb_code *pc, *pcend;
   mrb_code ins;
   const char *file = NULL, *next_file;
 
@@ -82,7 +82,7 @@ codedump(mrb_state *mrb, mrb_irep *irep)
 
     printf("local variable names:\n");
     for (i = 1; i < irep->nlocals; ++i) {
-      char const *s = mrb_sym2name(mrb, irep->lv[i - 1].name);
+      char const *s = mrb_sym_dump(mrb, irep->lv[i - 1].name);
       int n = irep->lv[i - 1].r ? irep->lv[i - 1].r : i;
       printf("  R%d:%s\n", n, s ? s : "");
     }
@@ -130,6 +130,10 @@ codedump(mrb_state *mrb, mrb_irep *irep)
       printf("OP_LOADI\tR%d\t-%d\t", a, b);
       print_lv_a(mrb, irep, a);
       break;
+    CASE(OP_LOADI16, BS):
+      printf("OP_LOADI16\tR%d\t%d\t", a, (int)(int16_t)b);
+      print_lv_a(mrb, irep, a);
+      break;
     CASE(OP_LOADI__1, B):
       printf("OP_LOADI__1\tR%d\t\t", a);
       print_lv_a(mrb, irep, a);
@@ -147,7 +151,7 @@ codedump(mrb_state *mrb, mrb_irep *irep)
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_LOADSYM, BB):
-      printf("OP_LOADSYM\tR%d\t:%s\t", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_LOADSYM\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_LOADNIL, B):
@@ -167,43 +171,43 @@ codedump(mrb_state *mrb, mrb_irep *irep)
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_GETGV, BB):
-      printf("OP_GETGV\tR%d\t:%s", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_GETGV\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_SETGV, BB):
-      printf("OP_SETGV\t:%s\tR%d", mrb_sym2name(mrb, irep->syms[b]), a);
+      printf("OP_SETGV\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_GETSV, BB):
-      printf("OP_GETSV\tR%d\t:%s", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_GETSV\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_SETSV, BB):
-      printf("OP_SETSV\t:%s\tR%d", mrb_sym2name(mrb, irep->syms[b]), a);
+      printf("OP_SETSV\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_GETCONST, BB):
-      printf("OP_GETCONST\tR%d\t:%s", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_GETCONST\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_SETCONST, BB):
-      printf("OP_SETCONST\t:%s\tR%d", mrb_sym2name(mrb, irep->syms[b]), a);
+      printf("OP_SETCONST\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_GETMCNST, BB):
-      printf("OP_GETMCNST\tR%d\tR%d::%s", a, a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_GETMCNST\tR%d\tR%d::%s", a, a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_SETMCNST, BB):
-      printf("OP_SETMCNST\tR%d::%s\tR%d", a+1, mrb_sym2name(mrb, irep->syms[b]), a);
+      printf("OP_SETMCNST\tR%d::%s\tR%d", a+1, mrb_sym_dump(mrb, irep->syms[b]), a);
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_GETIV, BB):
-      printf("OP_GETIV\tR%d\t%s", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_GETIV\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_SETIV, BB):
-      printf("OP_SETIV\t%s\tR%d", mrb_sym2name(mrb, irep->syms[b]), a);
+      printf("OP_SETIV\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_GETUPVAR, BBB):
@@ -215,11 +219,11 @@ codedump(mrb_state *mrb, mrb_irep *irep)
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_GETCV, BB):
-      printf("OP_GETCV\tR%d\t%s", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_GETCV\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_SETCV, BB):
-      printf("OP_SETCV\t%s\tR%d", mrb_sym2name(mrb, irep->syms[b]), a);
+      printf("OP_SETCV\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_JMP, S):
@@ -238,16 +242,16 @@ codedump(mrb_state *mrb, mrb_irep *irep)
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_SENDV, BB):
-      printf("OP_SENDV\tR%d\t:%s\n", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_SENDV\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b]));
       break;
     CASE(OP_SENDVB, BB):
-      printf("OP_SENDVB\tR%d\t:%s\n", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_SENDVB\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b]));
       break;
     CASE(OP_SEND, BBB):
-      printf("OP_SEND\tR%d\t:%s\t%d\n", a, mrb_sym2name(mrb, irep->syms[b]), c);
+      printf("OP_SEND\tR%d\t:%s\t%d\n", a, mrb_sym_dump(mrb, irep->syms[b]), c);
       break;
     CASE(OP_SENDB, BBB):
-      printf("OP_SENDB\tR%d\t:%s\t%d\n", a, mrb_sym2name(mrb, irep->syms[b]), c);
+      printf("OP_SENDB\tR%d\t:%s\t%d\n", a, mrb_sym_dump(mrb, irep->syms[b]), c);
       break;
     CASE(OP_CALL, Z):
       printf("OP_CALL\n");
@@ -266,23 +270,23 @@ codedump(mrb_state *mrb, mrb_irep *irep)
       break;
     CASE(OP_ENTER, W):
       printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n",
-             (a>>18)&0x1f,
-             (a>>13)&0x1f,
-             (a>>12)&0x1,
-             (a>>7)&0x1f,
-             (a>>2)&0x1f,
-             (a>>1)&0x1,
-             a & 0x1);
+             MRB_ASPEC_REQ(a),
+             MRB_ASPEC_OPT(a),
+             MRB_ASPEC_REST(a),
+             MRB_ASPEC_POST(a),
+             MRB_ASPEC_KEY(a),
+             MRB_ASPEC_KDICT(a),
+             MRB_ASPEC_BLOCK(a));
       break;
     CASE(OP_KEY_P, BB):
-      printf("OP_KEY_P\tR%d\t:%s\t", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_KEY_P\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_KEYEND, Z):
       printf("OP_KEYEND\n");
       break;
     CASE(OP_KARG, BB):
-      printf("OP_KARG\tR%d\t:%s\t", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_KARG\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_RETURN, B):
@@ -322,13 +326,13 @@ codedump(mrb_state *mrb, mrb_irep *irep)
       printf("OP_RANGE_EXC\tR%d\n", a);
       break;
     CASE(OP_DEF, BB):
-      printf("OP_DEF\tR%d\t:%s\n", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_DEF\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b]));
       break;
     CASE(OP_UNDEF, B):
-      printf("OP_UNDEF\t:%s\n", mrb_sym2name(mrb, irep->syms[a]));
+      printf("OP_UNDEF\t:%s\n", mrb_sym_dump(mrb, irep->syms[a]));
       break;
     CASE(OP_ALIAS, BB):
-      printf("OP_ALIAS\t:%s\t%s\n", mrb_sym2name(mrb, irep->syms[a]), mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_ALIAS\t:%s\t%s\n", mrb_sym_dump(mrb, irep->syms[a]), mrb_sym_dump(mrb, irep->syms[b]));
       break;
     CASE(OP_ADD, B):
       printf("OP_ADD\tR%d\t\n", a);
@@ -429,11 +433,11 @@ codedump(mrb_state *mrb, mrb_irep *irep)
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_CLASS, BB):
-      printf("OP_CLASS\tR%d\t:%s", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_CLASS\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_MODULE, BB):
-      printf("OP_MODULE\tR%d\t:%s", a, mrb_sym2name(mrb, irep->syms[b]));
+      printf("OP_MODULE\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
       print_lv_a(mrb, irep, a);
       break;
     CASE(OP_EXEC, BB):
index 0dc02a1..4aeed2f 100644 (file)
@@ -57,7 +57,7 @@ mrb_debug_get_filename(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc)
     mrb_irep_debug_info_file* f = NULL;
     if (!irep->debug_info) return NULL;
     else if ((f = get_file(irep->debug_info, (uint32_t)pc))) {
-      return mrb_sym2name_len(mrb, f->filename_sym, NULL);
+      return mrb_sym_name_len(mrb, f->filename_sym, NULL);
     }
   }
   return NULL;
@@ -138,7 +138,7 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d,
   mrb_assert(lines);
 
   if (d->flen > 0) {
-    const char *fn = mrb_sym2name_len(mrb, d->files[d->flen - 1]->filename_sym, NULL);
+    const char *fn = mrb_sym_name_len(mrb, d->files[d->flen - 1]->filename_sym, NULL);
     if (strcmp(filename, fn) == 0)
       return NULL;
   }
@@ -204,11 +204,14 @@ mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d)
 
   if (!d) { return; }
 
-  for (i = 0; i < d->flen; ++i) {
-    mrb_assert(d->files[i]);
-    mrb_free(mrb, d->files[i]->lines.ptr);
-    mrb_free(mrb, d->files[i]);
+  if (d->files) {
+    for (i = 0; i < d->flen; ++i) {
+      if (d->files[i]) {
+        mrb_free(mrb, d->files[i]->lines.ptr);
+        mrb_free(mrb, d->files[i]);
+      }
+    }
+    mrb_free(mrb, d->files);
   }
-  mrb_free(mrb, d->files);
   mrb_free(mrb, d);
 }
index f1e167e..a6bbe68 100644 (file)
@@ -13,9 +13,6 @@
 #include <mruby/numeric.h>
 #include <mruby/debug.h>
 
-#define FLAG_BYTEORDER_NATIVE 2
-#define FLAG_BYTEORDER_NONATIVE 0
-
 #ifndef MRB_WITHOUT_FLOAT
 #ifdef MRB_USE_FLOAT
 #define MRB_FLOAT_FMT "%.9g"
@@ -220,7 +217,7 @@ get_syms_block_size(mrb_state *mrb, mrb_irep *irep)
   for (sym_no = 0; sym_no < irep->slen; sym_no++) {
     size += sizeof(uint16_t); /* snl(n) */
     if (irep->syms[sym_no] != 0) {
-      mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
+      mrb_sym_name_len(mrb, irep->syms[sym_no], &len);
       size += len + 1; /* sn(n) + null char */
     }
   }
@@ -241,7 +238,7 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
     if (irep->syms[sym_no] != 0) {
       mrb_int len;
 
-      name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
+      name = mrb_sym_name_len(mrb, irep->syms[sym_no], &len);
 
       mrb_assert_int_fit(mrb_int, len, uint16_t, UINT16_MAX);
       cur += uint16_to_bin((uint16_t)len, cur); /* length of symbol name */
@@ -436,7 +433,7 @@ get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t *
       filenames[*lp - 1] = file->filename_sym;
 
       /* filename */
-      mrb_sym2name_len(mrb, file->filename_sym, &filename_len);
+      mrb_sym_name_len(mrb, file->filename_sym, &filename_len);
       size += sizeof(uint16_t) + (size_t)filename_len;
     }
   }
@@ -540,7 +537,7 @@ write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur, mrb_sym const
   cur += uint16_to_bin(filenames_len, cur);
   section_size += sizeof(uint16_t);
   for (i = 0; i < filenames_len; ++i) {
-    sym = mrb_sym2name_len(mrb, filenames[i], &sym_len);
+    sym = mrb_sym_name_len(mrb, filenames[i], &sym_len);
     mrb_assert(sym);
     cur += uint16_to_bin((uint16_t)sym_len, cur);
     memcpy(cur, sym, sym_len);
@@ -594,7 +591,7 @@ write_lv_sym_table(mrb_state *mrb, uint8_t **start, mrb_sym const *syms, uint32_
   cur += uint32_to_bin(syms_len, cur);
 
   for (i = 0; i < syms_len; ++i) {
-    str = mrb_sym2name_len(mrb, syms[i], &str_len);
+    str = mrb_sym_name_len(mrb, syms[i], &str_len);
     cur += uint16_to_bin((uint16_t)str_len, cur);
     memcpy(cur, str, str_len);
     cur += str_len;
@@ -658,7 +655,7 @@ get_lv_section_size(mrb_state *mrb, mrb_irep *irep, mrb_sym const *syms, uint32_
   ret += sizeof(uint16_t) * syms_len; /* symbol name lengths */
   for (i = 0; i < syms_len; ++i) {
     mrb_int str_len;
-    mrb_sym2name_len(mrb, syms[i], &str_len);
+    mrb_sym_name_len(mrb, syms[i], &str_len);
     ret += str_len;
   }
 
@@ -709,22 +706,7 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8
   uint16_t crc;
   uint32_t offset;
 
-  switch (flags & DUMP_ENDIAN_NAT) {
-  endian_big:
-  case DUMP_ENDIAN_BIG:
-    memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident));
-    break;
-  endian_little:
-  case DUMP_ENDIAN_LIL:
-    memcpy(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident));
-    break;
-
-  case DUMP_ENDIAN_NAT:
-    if (bigendian_p()) goto endian_big;
-    goto endian_little;
-    break;
-  }
-
+  memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident));
   memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version));
   memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name));
   memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version));
@@ -764,21 +746,6 @@ lv_defined_p(mrb_irep *irep)
   return FALSE;
 }
 
-static uint8_t
-dump_flags(uint8_t flags, uint8_t native)
-{
-  if (native == FLAG_BYTEORDER_NATIVE) {
-    if ((flags & DUMP_ENDIAN_NAT) == 0) {
-      return (flags & DUMP_DEBUG_INFO) | DUMP_ENDIAN_NAT;
-    }
-    return flags;
-  }
-  if ((flags & DUMP_ENDIAN_NAT) == 0) {
-    return (flags & DUMP_DEBUG_INFO) | DUMP_ENDIAN_BIG;
-  }
-  return flags;
-}
-
 static int
 dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size)
 {
@@ -870,7 +837,7 @@ error_exit:
 int
 mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size)
 {
-  return dump_irep(mrb, irep, dump_flags(flags, FLAG_BYTEORDER_NONATIVE), bin, bin_size);
+  return dump_irep(mrb, irep, flags, bin, bin_size);
 }
 
 #ifndef MRB_DISABLE_STDIO
@@ -886,7 +853,7 @@ mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE* fp)
     return MRB_DUMP_INVALID_ARGUMENT;
   }
 
-  result = dump_irep(mrb, irep, dump_flags(flags, FLAG_BYTEORDER_NONATIVE), &bin, &bin_size);
+  result = dump_irep(mrb, irep, flags, &bin, &bin_size);
   if (result == MRB_DUMP_OK) {
     if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) {
       result = MRB_DUMP_WRITE_FAULT;
@@ -897,20 +864,6 @@ mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE* fp)
   return result;
 }
 
-static mrb_bool
-dump_bigendian_p(uint8_t flags)
-{
-  switch (flags & DUMP_ENDIAN_NAT) {
-  case DUMP_ENDIAN_BIG:
-    return TRUE;
-  case DUMP_ENDIAN_LIL:
-    return FALSE;
-  default:
-  case DUMP_ENDIAN_NAT:
-    return bigendian_p();
-  }
-}
-
 int
 mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE *fp, const char *initname)
 {
@@ -921,29 +874,16 @@ mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE *fp, con
   if (fp == NULL || initname == NULL || initname[0] == '\0') {
     return MRB_DUMP_INVALID_ARGUMENT;
   }
-  flags = dump_flags(flags, FLAG_BYTEORDER_NATIVE);
   result = dump_irep(mrb, irep, flags, &bin, &bin_size);
   if (result == MRB_DUMP_OK) {
-    if (!dump_bigendian_p(flags)) {
-      if (fprintf(fp, "/* dumped in little endian order.\n"
-                  "   use `mrbc -E` option for big endian CPU. */\n") < 0) {
-        mrb_free(mrb, bin);
-        return MRB_DUMP_WRITE_FAULT;
-      }
-    }
-    else {
-      if (fprintf(fp, "/* dumped in big endian order.\n"
-                  "   use `mrbc -e` option for better performance on little endian CPU. */\n") < 0) {
-        mrb_free(mrb, bin);
-        return MRB_DUMP_WRITE_FAULT;
-      }
-    }
     if (fprintf(fp, "#include <stdint.h>\n") < 0) { /* for uint8_t under at least Darwin */
       mrb_free(mrb, bin);
       return MRB_DUMP_WRITE_FAULT;
     }
     if (fprintf(fp,
+          "#ifdef __cplusplus\n"
           "extern const uint8_t %s[];\n"
+          "#endif\n"
           "const uint8_t\n"
           "#if defined __GNUC__\n"
           "__attribute__((aligned(%u)))\n"
index 1e94451..d313701 100644 (file)
@@ -26,5 +26,5 @@ mrb_init_enumerable(mrb_state *mrb)
 {
   struct RClass *enumerable;
   enumerable = mrb_define_module(mrb, "Enumerable");  /* 15.3.2 */
-  mrb_define_module_function(mrb, enumerable, "__update_hash", enum_update_hash, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, enumerable, "__update_hash", enum_update_hash, MRB_ARGS_REQ(3));
 }
index e69812d..5d17209 100644 (file)
@@ -13,7 +13,6 @@
 #include <mruby/proc.h>
 #include <mruby/string.h>
 #include <mruby/variable.h>
-#include <mruby/debug.h>
 #include <mruby/error.h>
 #include <mruby/class.h>
 #include <mruby/throw.h>
@@ -44,10 +43,8 @@ static mrb_value
 exc_initialize(mrb_state *mrb, mrb_value exc)
 {
   mrb_value mesg;
-  mrb_int argc;
-  mrb_value *argv;
 
-  if (mrb_get_args(mrb, "|o*!", &mesg, &argv, &argc) >= 1) {
+  if (mrb_get_args(mrb, "|o", &mesg) == 1) {
     mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg);
   }
   return exc;
@@ -90,7 +87,7 @@ exc_exception(mrb_state *mrb, mrb_value self)
  * no message is set).
  */
 
-static mrb_value
+mrb_value
 exc_to_s(mrb_state *mrb, mrb_value exc)
 {
   mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
@@ -130,37 +127,13 @@ exc_message(mrb_state *mrb, mrb_value exc)
  * returns message and class name.
  */
 
-static mrb_value
-exc_inspect(mrb_state *mrb, mrb_value exc)
+mrb_value
+mrb_exc_inspect(mrb_state *mrb, mrb_value exc)
 {
-  mrb_value str, mesg, file, line;
-  mrb_bool append_mesg;
-  const char *cname;
-
-  mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
-  file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file"));
-  line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line"));
-
-  append_mesg = !mrb_nil_p(mesg);
-  if (append_mesg) {
-    mesg = mrb_obj_as_string(mrb, mesg);
-    append_mesg = RSTRING_LEN(mesg) > 0;
-  }
-
-  cname = mrb_obj_classname(mrb, exc);
-  str = mrb_str_new_cstr(mrb, cname);
-  if (mrb_string_p(file) && mrb_fixnum_p(line)) {
-    if (append_mesg) {
-      str = mrb_format(mrb, "%S:%S: %S (%S)", file, line, mesg, str);
-    }
-    else {
-      str = mrb_format(mrb, "%S:%S: %S", file, line, str);
-    }
-  }
-  else if (append_mesg) {
-    str = mrb_format(mrb, "%S: %S", str, mesg);
-  }
-  return str;
+  mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
+  mrb_value cname = mrb_mod_to_s(mrb, mrb_obj_value(mrb_obj_class(mrb, exc)));
+  mesg = mrb_obj_as_string(mrb, mesg);
+  return RSTRING_LEN(mesg) == 0 ? cname : mrb_format(mrb, "%v (%v)", mesg, cname);
 }
 
 void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc);
@@ -187,40 +160,12 @@ set_backtrace(mrb_state *mrb, mrb_value exc, mrb_value backtrace)
 static mrb_value
 exc_set_backtrace(mrb_state *mrb, mrb_value exc)
 {
-  mrb_value backtrace;
+  mrb_value backtrace = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &backtrace);
   set_backtrace(mrb, exc, backtrace);
   return backtrace;
 }
 
-static void
-exc_debug_info(mrb_state *mrb, struct RObject *exc)
-{
-  mrb_callinfo *ci = mrb->c->ci;
-  mrb_code *pc = ci->pc;
-
-  if (mrb_obj_iv_defined(mrb, exc, mrb_intern_lit(mrb, "file"))) return;
-  while (ci >= mrb->c->cibase) {
-    mrb_code *err = ci->err;
-
-    if (!err && pc) err = pc - 1;
-    if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
-      mrb_irep *irep = ci->proc->body.irep;
-
-      int32_t const line = mrb_debug_get_line(mrb, irep, err - irep->iseq);
-      char const* file = mrb_debug_get_filename(mrb, irep, err - irep->iseq);
-      if (line != -1 && file) {
-        mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file));
-        mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line));
-        return;
-      }
-    }
-    pc = ci->pc;
-    ci--;
-  }
-}
-
 void
 mrb_exc_set(mrb_state *mrb, mrb_value exc)
 {
@@ -233,20 +178,15 @@ mrb_exc_set(mrb_state *mrb, mrb_value exc)
         (struct RBasic*)mrb->exc == mrb->gc.arena[mrb->gc.arena_idx-1]) {
       mrb->gc.arena_idx--;
     }
-    if (!mrb->gc.out_of_memory && !MRB_FROZEN_P(mrb->exc)) {
-      exc_debug_info(mrb, mrb->exc);
+    if (!mrb->gc.out_of_memory && !mrb_frozen_p(mrb->exc)) {
       mrb_keep_backtrace(mrb, exc);
     }
   }
 }
 
-MRB_API mrb_noreturn void
-mrb_exc_raise(mrb_state *mrb, mrb_value exc)
+static mrb_noreturn void
+exc_throw(mrb_state *mrb, mrb_value exc)
 {
-  if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) {
-    mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");
-  }
-  mrb_exc_set(mrb, exc);
   if (!mrb->jmp) {
     mrb_p(mrb, exc);
     abort();
@@ -255,64 +195,176 @@ mrb_exc_raise(mrb_state *mrb, mrb_value exc)
 }
 
 MRB_API mrb_noreturn void
+mrb_exc_raise(mrb_state *mrb, mrb_value exc)
+{
+  if (mrb_break_p(exc)) {
+    mrb->exc = mrb_obj_ptr(exc);
+  }
+  else {
+    if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) {
+      mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");
+    }
+    mrb_exc_set(mrb, exc);
+  }
+  exc_throw(mrb, exc);
+}
+
+MRB_API mrb_noreturn void
 mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg)
 {
   mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mrb_str_new_cstr(mrb, msg)));
 }
 
+/*
+ * <code>vsprintf</code> like formatting.
+ *
+ * The syntax of a format sequence is as follows.
+ *
+ *   %[modifier]specifier
+ *
+ * The modifiers are:
+ *
+ *   ----------+------------------------------------------------------------
+ *   Modifier  | Meaning
+ *   ----------+------------------------------------------------------------
+ *       !     | Convert to string by corresponding `inspect` instead of
+ *             | corresponding `to_s`.
+ *   ----------+------------------------------------------------------------
+ *
+ * The specifiers are:
+ *
+ *   ----------+----------------+--------------------------------------------
+ *   Specifier | Argument Type  | Note
+ *   ----------+----------------+--------------------------------------------
+ *       c     | char           |
+ *       d     | int            |
+ *       f     | mrb_float      |
+ *       i     | mrb_int        |
+ *       l     | char*, size_t  | Arguments are string and length.
+ *       n     | mrb_sym        |
+ *       s     | char*          | Argument is NUL terminated string.
+ *       t     | mrb_value      | Convert to type (class) of object.
+ *      v,S    | mrb_value      |
+ *       C     | struct RClass* |
+ *       T     | mrb_value      | Convert to real type (class) of object.
+ *       Y     | mrb_value      | Same as `!v` if argument is `true`, `false`
+ *             |                | or `nil`, otherwise same as `T`.
+ *       %     | -              | Convert to percent sign itself (no argument
+ *             |                | taken).
+ *   ----------+----------------+--------------------------------------------
+ */
 MRB_API mrb_value
 mrb_vformat(mrb_state *mrb, const char *format, va_list ap)
 {
-  const char *p = format;
-  const char *b = p;
-  ptrdiff_t size;
-  int ai0 = mrb_gc_arena_save(mrb);
-  mrb_value ary = mrb_ary_new_capa(mrb, 4);
+  const char *chars, *p = format, *b = format, *e;
+  char ch;
+  size_t len;
+  mrb_int i;
+  struct RClass *cls;
+  mrb_bool inspect = FALSE;
+  mrb_value result = mrb_str_new_capa(mrb, 128), obj, str;
   int ai = mrb_gc_arena_save(mrb);
 
   while (*p) {
     const char c = *p++;
-
+    e = p;
     if (c == '%') {
-      if (*p == 'S') {
-        mrb_value val;
-
-        size = p - b - 1;
-        mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
-        val = va_arg(ap, mrb_value);
-        mrb_ary_push(mrb, ary, mrb_obj_as_string(mrb, val));
-        b = p + 1;
-      }
-    }
-    else if (c == '\\') {
-      if (*p) {
-        size = p - b - 1;
-        mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
-        mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, 1));
-        b = ++p;
+      if (*p == '!') {
+        inspect = TRUE;
+        ++p;
       }
-      else {
-        break;
+      if (!*p) break;
+      switch (*p) {
+        case 'c':
+          ch = (char)va_arg(ap, int);
+          chars = &ch;
+          len = 1;
+          goto L_cat;
+        case 'd': case 'i':
+#if MRB_INT_MAX < INT_MAX
+          i = (mrb_int)va_arg(ap, int);
+#else
+          i = *p == 'd' ? (mrb_int)va_arg(ap, int) : va_arg(ap, mrb_int);
+#endif
+          obj = mrb_fixnum_value(i);
+          goto L_cat_obj;
+#ifndef MRB_WITHOUT_FLOAT
+        case 'f':
+          obj = mrb_float_value(mrb, (mrb_float)va_arg(ap, double));
+          goto L_cat_obj;
+#endif
+        case 'l':
+          chars = va_arg(ap, char*);
+          len = va_arg(ap, size_t);
+        L_cat:
+          if (inspect) {
+            obj = mrb_str_new(mrb, chars, len);
+            goto L_cat_obj;
+          }
+          mrb_str_cat(mrb, result, b,  e - b - 1);
+          mrb_str_cat(mrb, result, chars, len);
+          b = ++p;
+          mrb_gc_arena_restore(mrb, ai);
+          break;
+        case 'n':
+#if UINT32_MAX < INT_MAX
+          obj = mrb_symbol_value((mrb_sym)va_arg(ap, int));
+#else
+          obj = mrb_symbol_value(va_arg(ap, mrb_sym));
+#endif
+          goto L_cat_obj;
+        case 's':
+          chars = va_arg(ap, char*);
+          len = strlen(chars);
+          goto L_cat;
+        case 't':
+          cls = mrb_class(mrb, va_arg(ap, mrb_value));
+          goto L_cat_class;
+        case 'v': case 'S':
+          obj = va_arg(ap, mrb_value);
+        L_cat_obj:
+          str = (inspect ? mrb_inspect : mrb_obj_as_string)(mrb, obj);
+          chars = RSTRING_PTR(str);
+          len = RSTRING_LEN(str);
+          inspect = FALSE;
+          goto L_cat;
+        case 'C':
+          cls = va_arg(ap, struct RClass*);
+        L_cat_class:
+          obj = mrb_obj_value(cls);
+          goto L_cat_obj;
+        case 'T':
+          obj = va_arg(ap, mrb_value);
+        L_cat_real_class_of:
+          cls = mrb_obj_class(mrb, obj);
+          goto L_cat_class;
+        case 'Y':
+          obj = va_arg(ap, mrb_value);
+          if (!mrb_test(obj) || mrb_true_p(obj)) {
+            inspect = TRUE;
+            goto L_cat_obj;
+          }
+          else {
+            goto L_cat_real_class_of;
+          }
+        case '%':
+        L_cat_current:
+          chars = p;
+          len = 1;
+          goto L_cat;
+        default:
+          mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p);
       }
     }
-    mrb_gc_arena_restore(mrb, ai);
-  }
-  if (b == format) {
-    mrb_gc_arena_restore(mrb, ai0);
-    return mrb_str_new_cstr(mrb, format);
-  }
-  else {
-    mrb_value val;
+    else if (c == '\\') {
+      if (!*p) break;
+      goto L_cat_current;
 
-    size = p - b;
-    if (size > 0) {
-      mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
     }
-    val = mrb_ary_join(mrb, ary, mrb_nil_value());
-    mrb_gc_arena_restore(mrb, ai0);
-    mrb_gc_protect(mrb, val);
-    return val;
   }
+
+  mrb_str_cat(mrb, result, b, p - b);
+  return result;
 }
 
 MRB_API mrb_value
@@ -434,7 +486,7 @@ exception_call:
 
       break;
     default:
-      mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc));
+      mrb_argnum_error(mrb, argc, 0, 3);
       break;
   }
   if (argc > 0) {
@@ -484,6 +536,71 @@ mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt,
   mrb_exc_raise(mrb, exc);
 }
 
+MRB_API mrb_noreturn void
+mrb_frozen_error(mrb_state *mrb, void *frozen_obj)
+{
+  mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", mrb_obj_value(frozen_obj));
+}
+
+MRB_API mrb_noreturn void
+mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max)
+{
+#define FMT(exp) "wrong number of arguments (given %i, expected " exp ")"
+  if (min == max)
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d"), argc, min);
+  else if (max < 0)
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d+"), argc, min);
+  else
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d..%d"), argc, min, max);
+#undef FMT
+}
+
+void mrb_core_init_printabort(void);
+
+int
+mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state *, void *), void *opaque)
+{
+  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+  struct mrb_jmpbuf c_jmp;
+  int err = 1;
+
+  MRB_TRY(&c_jmp) {
+    mrb->jmp = &c_jmp;
+    body(mrb, opaque);
+    err = 0;
+  } MRB_CATCH(&c_jmp) {
+    if (mrb->exc) {
+      mrb_p(mrb, mrb_obj_value(mrb->exc));
+      mrb->exc = NULL;
+    }
+    else {
+      mrb_core_init_printabort();
+    }
+  } MRB_END_EXC(&c_jmp);
+
+  mrb->jmp = prev_jmp;
+
+  return err;
+}
+
+mrb_noreturn void
+mrb_core_init_abort(mrb_state *mrb)
+{
+  mrb->exc = NULL;
+  exc_throw(mrb, mrb_nil_value());
+}
+
+mrb_noreturn void
+mrb_raise_nomemory(mrb_state *mrb)
+{
+  if (mrb->nomem_err) {
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
+  }
+  else {
+    mrb_core_init_abort(mrb);
+  }
+}
+
 void
 mrb_init_exception(mrb_state *mrb)
 {
@@ -491,12 +608,12 @@ mrb_init_exception(mrb_state *mrb)
 
   mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */
   MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION);
-  mrb_define_class_method(mrb, exception, "exception", mrb_instance_new,  MRB_ARGS_ANY());
-  mrb_define_method(mrb, exception, "exception",       exc_exception,     MRB_ARGS_ANY());
-  mrb_define_method(mrb, exception, "initialize",      exc_initialize,    MRB_ARGS_ANY());
+  mrb_define_class_method(mrb, exception, "exception", mrb_instance_new,  MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, exception, "exception",       exc_exception,     MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, exception, "initialize",      exc_initialize,    MRB_ARGS_OPT(1));
   mrb_define_method(mrb, exception, "to_s",            exc_to_s,          MRB_ARGS_NONE());
   mrb_define_method(mrb, exception, "message",         exc_message,       MRB_ARGS_NONE());
-  mrb_define_method(mrb, exception, "inspect",         exc_inspect,       MRB_ARGS_NONE());
+  mrb_define_method(mrb, exception, "inspect",         mrb_exc_inspect,   MRB_ARGS_NONE());
   mrb_define_method(mrb, exception, "backtrace",       mrb_exc_backtrace, MRB_ARGS_NONE());
   mrb_define_method(mrb, exception, "set_backtrace",   exc_set_backtrace, MRB_ARGS_REQ(1));
 
index 12d948a..785f493 100644 (file)
@@ -1,5 +1,5 @@
 /*
-** etc.c -
+** etc.c
 **
 ** See Copyright Notice in mruby.h
 */
@@ -8,8 +8,6 @@
 #include <mruby/string.h>
 #include <mruby/data.h>
 #include <mruby/class.h>
-#include <mruby/re.h>
-#include <mruby/irep.h>
 
 MRB_API struct RData*
 mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb_data_type *type)
@@ -26,21 +24,19 @@ mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb
 MRB_API void
 mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
 {
-  if (mrb_type(obj) != MRB_TT_DATA) {
+  if (!mrb_data_p(obj)) {
     mrb_check_type(mrb, obj, MRB_TT_DATA);
   }
   if (DATA_TYPE(obj) != type) {
     const mrb_data_type *t2 = DATA_TYPE(obj);
 
     if (t2) {
-      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)",
-                 mrb_str_new_cstr(mrb, t2->struct_name), mrb_str_new_cstr(mrb, type->struct_name));
+      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)",
+                 t2->struct_name, type->struct_name);
     }
     else {
-      struct RClass *c = mrb_class(mrb, obj);
-
-      mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %S (expected %S)",
-                 mrb_obj_value(c), mrb_str_new_cstr(mrb, type->struct_name));
+      mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %t (expected %s)",
+                 obj, type->struct_name);
     }
   }
 }
@@ -48,7 +44,7 @@ mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
 MRB_API void*
 mrb_data_check_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
 {
-  if (mrb_type(obj) != MRB_TT_DATA) {
+  if (!mrb_data_p(obj)) {
     return NULL;
   }
   if (DATA_TYPE(obj) != type) {
@@ -67,24 +63,10 @@ mrb_data_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
 MRB_API mrb_sym
 mrb_obj_to_sym(mrb_state *mrb, mrb_value name)
 {
-  mrb_sym id;
-
-  switch (mrb_type(name)) {
-    default:
-      name = mrb_check_string_type(mrb, name);
-      if (mrb_nil_p(name)) {
-        name = mrb_inspect(mrb, name);
-        mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", name);
-        /* not reached */
-      }
-      /* fall through */
-    case MRB_TT_STRING:
-      name = mrb_str_intern(mrb, name);
-      /* fall through */
-    case MRB_TT_SYMBOL:
-      id = mrb_symbol(name);
-  }
-  return id;
+  if (mrb_symbol_p(name)) return mrb_symbol(name);
+  if (mrb_string_p(name)) return mrb_intern_str(mrb, name);
+  mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a symbol nor a string", name);
+  return 0;  /* not reached */
 }
 
 MRB_API mrb_int
@@ -150,7 +132,6 @@ mrb_obj_id(mrb_value obj)
   case MRB_TT_HASH:
   case MRB_TT_RANGE:
   case MRB_TT_EXCEPTION:
-  case MRB_TT_FILE:
   case MRB_TT_DATA:
   case MRB_TT_ISTRUCT:
   default:
@@ -158,7 +139,13 @@ mrb_obj_id(mrb_value obj)
   }
 }
 
+#if defined(MRB_NAN_BOXING) && defined(MRB_64BIT)
+#define mrb_xxx_boxing_cptr_value mrb_nan_boxing_cptr_value
+#endif
+
 #ifdef MRB_WORD_BOXING
+#define mrb_xxx_boxing_cptr_value mrb_word_boxing_cptr_value
+
 #ifndef MRB_WITHOUT_FLOAT
 MRB_API mrb_value
 mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f)
@@ -167,6 +154,7 @@ mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f)
 
   v.value.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class);
   v.value.fp->f = f;
+  MRB_SET_FROZEN_FLAG(v.value.bp);
   return v;
 }
 
@@ -177,37 +165,24 @@ mrb_word_boxing_float_pool(mrb_state *mrb, mrb_float f)
   nf->tt = MRB_TT_FLOAT;
   nf->c = mrb->float_class;
   nf->f = f;
+  MRB_SET_FROZEN_FLAG(nf);
   return mrb_obj_value(nf);
 }
 #endif  /* MRB_WITHOUT_FLOAT */
+#endif  /* MRB_WORD_BOXING */
 
+#if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_64BIT))
 MRB_API mrb_value
-mrb_word_boxing_cptr_value(mrb_state *mrb, void *p)
+mrb_xxx_boxing_cptr_value(mrb_state *mrb, void *p)
 {
   mrb_value v;
+  struct RCptr *cptr = (struct RCptr*)mrb_obj_alloc(mrb, MRB_TT_CPTR, mrb->object_class);
 
-  v.value.p = mrb_obj_alloc(mrb, MRB_TT_CPTR, mrb->object_class);
-  v.value.vp->p = p;
+  SET_OBJ_VALUE(v, cptr);
+  cptr->p = p;
   return v;
 }
-#endif  /* MRB_WORD_BOXING */
-
-MRB_API mrb_bool
-mrb_regexp_p(mrb_state *mrb, mrb_value v)
-{
-  if (mrb->flags & MRB_STATE_NO_REGEXP) {
-    return FALSE;
-  }
-  if ((mrb->flags & MRB_STATE_REGEXP) || mrb_class_defined(mrb, REGEXP_CLASS)) {
-    mrb->flags |= MRB_STATE_REGEXP;
-    return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS));
-  }
-  else {
-    mrb->flags |= MRB_STATE_REGEXP;
-    mrb->flags |= MRB_STATE_NO_REGEXP;
-  }
-  return FALSE;
-}
+#endif
 
 #if defined _MSC_VER && _MSC_VER < 1900
 
index 14c74ef..81ace6e 100644 (file)
@@ -30,7 +30,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include <limits.h>
 #include <string.h>
-#include <stdint.h>
 #include <math.h>
 #include <float.h>
 #include <ctype.h>
@@ -38,9 +37,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <mruby.h>
 #include <mruby/string.h>
 
+struct fmt_args;
+
+typedef void output_func(struct fmt_args *f, const char *s, size_t l);
+
 struct fmt_args {
   mrb_state *mrb;
-  mrb_value str;
+  output_func *output;
+  void *opaque;
+};
+
+struct mrb_cstr {
+  char *buf;
+  size_t len;
 };
 
 #define MAX(a,b) ((a)>(b) ? (a) : (b))
@@ -55,15 +64,44 @@ struct fmt_args {
 #define PAD_POS    (1U<<(' '-' '))
 #define MARK_POS   (1U<<('+'-' '))
 
+#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS)
+
+static output_func strcat_value;
+static output_func strcat_cstr;
+
+static void
+strcat_value(struct fmt_args *f, const char *s, size_t l)
+{
+  mrb_value str = *(mrb_value*)f->opaque;
+  mrb_str_cat(f->mrb, str, s, l);
+}
+
+static void
+strcat_cstr(struct fmt_args *f, const char *s, size_t l)
+{
+  struct mrb_cstr *cstr = (struct mrb_cstr*)f->opaque;
+
+  if (l > cstr->len) {
+    mrb_state *mrb = f->mrb;
+
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "string buffer too small");
+  }
+
+  memcpy(cstr->buf, s, l);
+
+  cstr->buf += l;
+  cstr->len -= l;
+}
+
 static void
 out(struct fmt_args *f, const char *s, size_t l)
 {
-  mrb_str_cat(f->mrb, f->str, s, l);
+  f->output(f, s, l);
 }
 
 #define PAD_SIZE 256
 static void
-pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint8_t fl)
+pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint32_t fl)
 {
   char pad[PAD_SIZE];
   if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
@@ -93,7 +131,7 @@ typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)
 #endif
 
 static int
-fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
+fmt_fp(struct fmt_args *f, long double y, ptrdiff_t w, ptrdiff_t p, uint32_t fl, int t)
 {
   uint32_t big[(LDBL_MANT_DIG+28)/29 + 1          // mantissa expansion
     + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion
@@ -118,11 +156,11 @@ fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
   if (!isfinite(y)) {
     const char *ss = (t&32)?"inf":"INF";
     if (y!=y) ss=(t&32)?"nan":"NAN";
-    pad(f, ' ', 0, 3+pl, fl&~ZERO_PAD);
+    pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
     out(f, prefix, pl);
     out(f, ss, 3);
-    pad(f, ' ', 0, 3+pl, fl^LEFT_ADJ);
-    return 3+(int)pl;
+    pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
+    return (int)MAX(w, 3+pl);
   }
 
   y = frexp((double)y, &e2) * 2;
@@ -170,14 +208,14 @@ fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
     else
       l = (s-buf) + (ebuf-estr);
 
-    pad(f, ' ', 0, pl+l, fl);
+    pad(f, ' ', w, pl+l, fl);
     out(f, prefix, pl);
-    pad(f, '0', 0, pl+l, fl^ZERO_PAD);
+    pad(f, '0', w, pl+l, fl^ZERO_PAD);
     out(f, buf, s-buf);
     pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
     out(f, estr, ebuf-estr);
-    pad(f, ' ', 0, pl+l, fl^LEFT_ADJ);
-    return (int)pl+(int)l;
+    pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+    return (int)MAX(w, pl+l);
   }
   if (p<0) p=6;
 
@@ -289,9 +327,9 @@ fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
     l += ebuf-estr;
   }
 
-  pad(f, ' ', 0, pl+l, fl);
+  pad(f, ' ', w, pl+l, fl);
   out(f, prefix, pl);
-  pad(f, '0', 0, pl+l, fl^ZERO_PAD);
+  pad(f, '0', w, pl+l, fl^ZERO_PAD);
 
   if ((t|32)=='f') {
     if (a>r) a=r;
@@ -326,21 +364,33 @@ fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
     out(f, estr, ebuf-estr);
   }
 
-  pad(f, ' ', 0, pl+l, fl^LEFT_ADJ);
+  pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
 
-  return (int)pl+(int)l;
+  return (int)MAX(w, pl+l);
 }
 
 static int
 fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo)
 {
-  ptrdiff_t p;
+  ptrdiff_t w, p;
+  uint32_t fl;
 
   if (*fmt != '%') {
     return -1;
   }
   ++fmt;
 
+  /* Read modifier flags */
+  for (fl=0; (unsigned)*fmt-' '<32 && (FLAGMASK&(1U<<(*fmt-' '))); fmt++)
+    fl |= 1U<<(*fmt-' ');
+
+  /* - and 0 flags are mutually exclusive */
+  if (fl & LEFT_ADJ) fl &= ~ZERO_PAD;
+
+  for (w = 0; ISDIGIT(*fmt); ++fmt) {
+    w = 10 * w + (*fmt - '0');
+  }
+
   if (*fmt == '.') {
     ++fmt;
     for (p = 0; ISDIGIT(*fmt); ++fmt) {
@@ -354,29 +404,49 @@ fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo)
   switch (*fmt) {
   case 'e': case 'f': case 'g': case 'a':
   case 'E': case 'F': case 'G': case 'A':
-    return fmt_fp(f, flo, p, 0, *fmt);
+    return fmt_fp(f, flo, w, p, fl, *fmt);
   default:
     return -1;
   }
 }
 
-mrb_value
+MRB_API mrb_value
 mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
 {
   struct fmt_args f;
+  mrb_value str = mrb_str_new_capa(mrb, 24);
 
   f.mrb = mrb;
-  f.str = mrb_str_new_capa(mrb, 24);
+  f.output = strcat_value;
+  f.opaque = (void*)&str;
   if (fmt_core(&f, fmt, mrb_float(flo)) < 0) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string");
   }
-  return f.str;
+  return str;
 }
-#else   /* MRB_DISABLE_STDIO */
+
+MRB_API int
+mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float fval)
+{
+  struct fmt_args f;
+  struct mrb_cstr cstr;
+
+  cstr.buf = buf;
+  cstr.len = len - 1; /* reserve NUL terminator */
+  f.mrb = mrb;
+  f.output = strcat_cstr;
+  f.opaque = (void*)&cstr;
+  if (fmt_core(&f, fmt, fval) < 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string");
+  }
+  *cstr.buf = '\0';
+  return (int)(cstr.buf - buf);
+}
+#else   /* MRB_DISABLE_STDIO || _WIN32 || _WIN64 */
 #include <mruby.h>
 #include <stdio.h>
 
-mrb_value
+MRB_API mrb_value
 mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
 {
   char buf[25];
@@ -384,5 +454,11 @@ mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
   snprintf(buf, sizeof(buf), fmt, mrb_float(flo));
   return mrb_str_new_cstr(mrb, buf);
 }
-#endif  /* MRB_DISABLE_STDIO */
+
+MRB_API int
+mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float fval)
+{
+  return snprintf(buf, len, fmt, fval);
+}
+#endif  /* MRB_DISABLE_STDIO || _WIN32 || _WIN64 */
 #endif
index ec52787..03c561d 100644 (file)
@@ -10,6 +10,7 @@
 #include <mruby/array.h>
 #include <mruby/class.h>
 #include <mruby/data.h>
+#include <mruby/istruct.h>
 #include <mruby/hash.h>
 #include <mruby/proc.h>
 #include <mruby/range.h>
@@ -109,8 +110,10 @@ typedef struct {
     struct RHash hash;
     struct RRange range;
     struct RData data;
+    struct RIStruct istruct;
     struct RProc proc;
     struct REnv env;
+    struct RFiber fiber;
     struct RException exc;
     struct RBreak brk;
 #ifdef MRB_WORD_BOXING
@@ -198,6 +201,8 @@ gettimeofday_time(void)
 
 #define objects(p) ((RVALUE *)p->objects)
 
+mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb);
+
 MRB_API void*
 mrb_realloc_simple(mrb_state *mrb, void *p,  size_t len)
 {
@@ -221,12 +226,12 @@ mrb_realloc(mrb_state *mrb, void *p, size_t len)
   if (len == 0) return p2;
   if (p2 == NULL) {
     if (mrb->gc.out_of_memory) {
-      mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
+      mrb_raise_nomemory(mrb);
       /* mrb_panic(mrb); */
     }
     else {
       mrb->gc.out_of_memory = TRUE;
-      mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
+      mrb_raise_nomemory(mrb);
     }
   }
   else {
@@ -274,6 +279,14 @@ mrb_free(mrb_state *mrb, void *p)
   (mrb->allocf)(mrb, p, 0, mrb->allocf_ud);
 }
 
+MRB_API void*
+mrb_alloca(mrb_state *mrb, size_t size)
+{
+  struct RString *s;
+  s = (struct RString*)mrb_obj_alloc(mrb, MRB_TT_STRING, mrb->string_class);
+  return s->as.heap.ptr = (char*)mrb_malloc(mrb, size);
+}
+
 static mrb_bool
 heap_p(mrb_gc *gc, struct RBasic *object)
 {
@@ -396,7 +409,7 @@ mrb_gc_init(mrb_state *mrb, mrb_gc *gc)
 
 static void obj_free(mrb_state *mrb, struct RBasic *obj, int end);
 
-void
+static void
 free_heap(mrb_state *mrb, mrb_gc *gc)
 {
   mrb_heap_page *page = gc->heaps;
@@ -463,10 +476,13 @@ mrb_gc_protect(mrb_state *mrb, mrb_value obj)
 MRB_API void
 mrb_gc_register(mrb_state *mrb, mrb_value obj)
 {
-  mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);
-  mrb_value table = mrb_gv_get(mrb, root);
+  mrb_sym root;
+  mrb_value table;
 
-  if (mrb_nil_p(table) || mrb_type(table) != MRB_TT_ARRAY) {
+  if (mrb_immediate_p(obj)) return;
+  root = mrb_intern_lit(mrb, GC_ROOT_NAME);
+  table = mrb_gv_get(mrb, root);
+  if (mrb_nil_p(table) || !mrb_array_p(table)) {
     table = mrb_ary_new(mrb);
     mrb_gv_set(mrb, root, table);
   }
@@ -477,20 +493,23 @@ mrb_gc_register(mrb_state *mrb, mrb_value obj)
 MRB_API void
 mrb_gc_unregister(mrb_state *mrb, mrb_value obj)
 {
-  mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);
-  mrb_value table = mrb_gv_get(mrb, root);
+  mrb_sym root;
+  mrb_value table;
   struct RArray *a;
   mrb_int i;
 
+  if (mrb_immediate_p(obj)) return;
+  root = mrb_intern_lit(mrb, GC_ROOT_NAME);
+  table = mrb_gv_get(mrb, root);
   if (mrb_nil_p(table)) return;
-  if (mrb_type(table) != MRB_TT_ARRAY) {
+  if (!mrb_array_p(table)) {
     mrb_gv_set(mrb, root, mrb_nil_value());
     return;
   }
   a = mrb_ary_ptr(table);
   mrb_ary_modify(mrb, a);
   for (i = 0; i < ARY_LEN(a); i++) {
-    if (mrb_obj_eq(mrb, ARY_PTR(a)[i], obj)) {
+    if (mrb_ptr(ARY_PTR(a)[i]) == mrb_ptr(obj)) {
       mrb_int len = ARY_LEN(a)-1;
       mrb_value *ptr = ARY_PTR(a);
 
@@ -505,7 +524,7 @@ MRB_API struct RBasic*
 mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
 {
   struct RBasic *p;
-  static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } };
+  static const RVALUE RVALUE_zero = { { { NULL, NULL, MRB_TT_FALSE } } };
   mrb_gc *gc = &mrb->gc;
 
   if (cls) {
@@ -526,7 +545,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
         ttype != MRB_TT_ICLASS &&
         ttype != MRB_TT_ENV &&
         ttype != tt) {
-      mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %S", mrb_obj_value(cls));
+      mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C", cls);
     }
   }
 
@@ -697,10 +716,10 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
       struct REnv *e = (struct REnv*)obj;
       mrb_int i, len;
 
-      if (MRB_ENV_STACK_SHARED_P(e) && e->cxt && e->cxt->fib) {
+      if (MRB_ENV_ONSTACK_P(e) && e->cxt && e->cxt->fib) {
         mrb_gc_mark(mrb, (struct RBasic*)e->cxt->fib);
       }
-      len = MRB_ENV_STACK_LEN(e);
+      len = MRB_ENV_LEN(e);
       for (i=0; i<len; i++) {
         mrb_gc_mark_value(mrb, e->stack[i]);
       }
@@ -732,7 +751,7 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
     break;
 
   case MRB_TT_STRING:
-    if (RSTR_FSHARED_P(obj) && !RSTR_NOFREE_P(obj)) {
+    if (RSTR_FSHARED_P(obj)) {
       struct RString *s = (struct RString*)obj;
       mrb_gc_mark(mrb, (struct RBasic*)s->as.heap.aux.fshared);
     }
@@ -790,16 +809,18 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
   case MRB_TT_SCLASS:
     mrb_gc_free_mt(mrb, (struct RClass*)obj);
     mrb_gc_free_iv(mrb, (struct RObject*)obj);
+    mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
     break;
   case MRB_TT_ICLASS:
     if (MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN))
       mrb_gc_free_mt(mrb, (struct RClass*)obj);
+    mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
     break;
   case MRB_TT_ENV:
     {
       struct REnv *e = (struct REnv*)obj;
 
-      if (MRB_ENV_STACK_SHARED_P(e)) {
+      if (MRB_ENV_ONSTACK_P(e)) {
         /* cannot be freed */
         e->stack = NULL;
         break;
@@ -821,7 +842,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
           while (ce <= ci) {
             struct REnv *e = ci->env;
             if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) &&
-                e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) {
+                e->tt == MRB_TT_ENV && MRB_ENV_ONSTACK_P(e)) {
               mrb_env_unshare(mrb, e);
             }
             ci--;
@@ -939,13 +960,12 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc)
   }
 }
 
+/* rough estimation of number of GC marks (non recursive) */
 static size_t
-gc_gray_mark(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
+gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
 {
   size_t children = 0;
 
-  gc_mark_children(mrb, gc, obj);
-
   switch (obj->tt) {
   case MRB_TT_ICLASS:
     children++;
@@ -970,7 +990,7 @@ gc_gray_mark(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
     break;
 
   case MRB_TT_ENV:
-    children += MRB_ENV_STACK_LEN(obj);
+    children += MRB_ENV_LEN(obj);
     break;
 
   case MRB_TT_FIBER:
@@ -1043,7 +1063,9 @@ incremental_marking_phase(mrb_state *mrb, mrb_gc *gc, size_t limit)
   size_t tried_marks = 0;
 
   while (gc->gray_list && tried_marks < limit) {
-    tried_marks += gc_gray_mark(mrb, gc, gc->gray_list);
+    struct RBasic *obj = gc->gray_list;
+    gc_mark_children(mrb, gc, obj);
+    tried_marks += gc_gray_counts(mrb, gc, obj);
   }
 
   return tried_marks;
@@ -1275,6 +1297,7 @@ mrb_full_gc(mrb_state *mrb)
 {
   mrb_gc *gc = &mrb->gc;
 
+  if (!mrb->c) return;
   if (gc->disabled || gc->iterating) return;
 
   GC_INVOKE_TIME_REPORT("mrb_full_gc()");
@@ -1593,6 +1616,9 @@ mrb_init_gc(mrb_state *mrb)
 {
   struct RClass *gc;
 
+  mrb_static_assert(sizeof(RVALUE) <= sizeof(void*) * 6,
+                    "RVALUE size must be within 6 words");
+
   gc = mrb_define_module(mrb, "GC");
 
   mrb_define_class_method(mrb, gc, "start", gc_start, MRB_ARGS_NONE());
@@ -1610,272 +1636,3 @@ mrb_init_gc(mrb_state *mrb)
 #endif
 #endif
 }
-
-#ifdef GC_TEST
-#ifdef GC_DEBUG
-void
-test_mrb_field_write_barrier(void)
-{
-  mrb_state *mrb = mrb_open();
-  struct RBasic *obj, *value;
-  mrb_gc *gc = &mrb->gc;
-
-  puts("test_mrb_field_write_barrier");
-  gc->generational = FALSE;
-  obj = mrb_basic_ptr(mrb_ary_new(mrb));
-  value = mrb_basic_ptr(mrb_str_new_lit(mrb, "value"));
-  paint_black(obj);
-  paint_partial_white(gc, value);
-
-
-  puts("  in MRB_GC_STATE_MARK");
-  gc->state = MRB_GC_STATE_MARK;
-  mrb_field_write_barrier(mrb, obj, value);
-
-  mrb_assert(is_gray(value));
-
-
-  puts("  in MRB_GC_STATE_SWEEP");
-  paint_partial_white(gc, value);
-  gc->state = MRB_GC_STATE_SWEEP;
-  mrb_field_write_barrier(mrb, obj, value);
-
-  mrb_assert(obj->color & gc->current_white_part);
-  mrb_assert(value->color & gc->current_white_part);
-
-
-  puts("  fail with black");
-  gc->state = MRB_GC_STATE_MARK;
-  paint_white(obj);
-  paint_partial_white(gc, value);
-  mrb_field_write_barrier(mrb, obj, value);
-
-  mrb_assert(obj->color & gc->current_white_part);
-
-
-  puts("  fail with gray");
-  gc->state = MRB_GC_STATE_MARK;
-  paint_black(obj);
-  paint_gray(value);
-  mrb_field_write_barrier(mrb, obj, value);
-
-  mrb_assert(is_gray(value));
-
-
-  {
-    puts("test_mrb_field_write_barrier_value");
-    obj = mrb_basic_ptr(mrb_ary_new(mrb));
-    mrb_value value = mrb_str_new_lit(mrb, "value");
-    paint_black(obj);
-    paint_partial_white(gc, mrb_basic_ptr(value));
-
-    gc->state = MRB_GC_STATE_MARK;
-    mrb_field_write_barrier_value(mrb, obj, value);
-
-    mrb_assert(is_gray(mrb_basic_ptr(value)));
-  }
-
-  mrb_close(mrb);
-}
-
-void
-test_mrb_write_barrier(void)
-{
-  mrb_state *mrb = mrb_open();
-  struct RBasic *obj;
-  mrb_gc *gc = &mrb->gc;
-
-  puts("test_mrb_write_barrier");
-  obj = mrb_basic_ptr(mrb_ary_new(mrb));
-  paint_black(obj);
-
-  puts("  in MRB_GC_STATE_MARK");
-  gc->state = MRB_GC_STATE_MARK;
-  mrb_write_barrier(mrb, obj);
-
-  mrb_assert(is_gray(obj));
-  mrb_assert(gc->atomic_gray_list == obj);
-
-
-  puts("  fail with gray");
-  paint_gray(obj);
-  mrb_write_barrier(mrb, obj);
-
-  mrb_assert(is_gray(obj));
-
-  mrb_close(mrb);
-}
-
-void
-test_add_gray_list(void)
-{
-  mrb_state *mrb = mrb_open();
-  struct RBasic *obj1, *obj2;
-  mrb_gc *gc = &mrb->gc;
-
-  puts("test_add_gray_list");
-  change_gen_gc_mode(mrb, gc, FALSE);
-  mrb_assert(gc->gray_list == NULL);
-  obj1 = mrb_basic_ptr(mrb_str_new_lit(mrb, "test"));
-  add_gray_list(mrb, gc, obj1);
-  mrb_assert(gc->gray_list == obj1);
-  mrb_assert(is_gray(obj1));
-
-  obj2 = mrb_basic_ptr(mrb_str_new_lit(mrb, "test"));
-  add_gray_list(mrb, gc, obj2);
-  mrb_assert(gc->gray_list == obj2);
-  mrb_assert(gc->gray_list->gcnext == obj1);
-  mrb_assert(is_gray(obj2));
-
-  mrb_close(mrb);
-}
-
-void
-test_gc_gray_mark(void)
-{
-  mrb_state *mrb = mrb_open();
-  mrb_value obj_v, value_v;
-  struct RBasic *obj;
-  size_t gray_num = 0;
-  mrb_gc *gc = &mrb->gc;
-
-  puts("test_gc_gray_mark");
-
-  puts("  in MRB_TT_CLASS");
-  obj = (struct RBasic*)mrb->object_class;
-  paint_gray(obj);
-  gray_num = gc_gray_mark(mrb, gc, obj);
-  mrb_assert(is_black(obj));
-  mrb_assert(gray_num > 1);
-
-  puts("  in MRB_TT_ARRAY");
-  obj_v = mrb_ary_new(mrb);
-  value_v = mrb_str_new_lit(mrb, "test");
-  paint_gray(mrb_basic_ptr(obj_v));
-  paint_partial_white(gc, mrb_basic_ptr(value_v));
-  mrb_ary_push(mrb, obj_v, value_v);
-  gray_num = gc_gray_mark(mrb, gc, mrb_basic_ptr(obj_v));
-  mrb_assert(is_black(mrb_basic_ptr(obj_v)));
-  mrb_assert(is_gray(mrb_basic_ptr(value_v)));
-  mrb_assert(gray_num == 1);
-
-  mrb_close(mrb);
-}
-
-void
-test_incremental_gc(void)
-{
-  mrb_state *mrb = mrb_open();
-  size_t max = ~0, live = 0, total = 0, freed = 0;
-  RVALUE *free;
-  mrb_heap_page *page;
-  mrb_gc *gc = &mrb->gc;
-
-  puts("test_incremental_gc");
-  change_gen_gc_mode(mrb, gc, FALSE);
-
-  puts("  in mrb_full_gc");
-  mrb_full_gc(mrb);
-
-  mrb_assert(gc->state == MRB_GC_STATE_ROOT);
-  puts("  in MRB_GC_STATE_ROOT");
-  incremental_gc(mrb, gc, max);
-  mrb_assert(gc->state == MRB_GC_STATE_MARK);
-  puts("  in MRB_GC_STATE_MARK");
-  incremental_gc_until(mrb, gc, MRB_GC_STATE_SWEEP);
-  mrb_assert(gc->state == MRB_GC_STATE_SWEEP);
-
-  puts("  in MRB_GC_STATE_SWEEP");
-  page = gc->heaps;
-  while (page) {
-    RVALUE *p = objects(page);
-    RVALUE *e = p + MRB_HEAP_PAGE_SIZE;
-    while (p<e) {
-      if (is_black(&p->as.basic)) {
-        live++;
-      }
-      if (is_gray(&p->as.basic) && !is_dead(gc, &p->as.basic)) {
-        printf("%p\n", &p->as.basic);
-      }
-      p++;
-    }
-    page = page->next;
-    total += MRB_HEAP_PAGE_SIZE;
-  }
-
-  mrb_assert(gc->gray_list == NULL);
-
-  incremental_gc(mrb, gc, max);
-  mrb_assert(gc->state == MRB_GC_STATE_SWEEP);
-
-  incremental_gc(mrb, gc, max);
-  mrb_assert(gc->state == MRB_GC_STATE_ROOT);
-
-  free = (RVALUE*)gc->heaps->freelist;
-  while (free) {
-   freed++;
-   free = (RVALUE*)free->as.free.next;
-  }
-
-  mrb_assert(gc->live == live);
-  mrb_assert(gc->live == total-freed);
-
-  puts("test_incremental_gc(gen)");
-  incremental_gc_until(mrb, gc, MRB_GC_STATE_SWEEP);
-  change_gen_gc_mode(mrb, gc, TRUE);
-
-  mrb_assert(gc->full == FALSE);
-  mrb_assert(gc->state == MRB_GC_STATE_ROOT);
-
-  puts("  in minor");
-  mrb_assert(is_minor_gc(gc));
-  mrb_assert(gc->majorgc_old_threshold > 0);
-  gc->majorgc_old_threshold = 0;
-  mrb_incremental_gc(mrb);
-  mrb_assert(gc->full == TRUE);
-  mrb_assert(gc->state == MRB_GC_STATE_ROOT);
-
-  puts("  in major");
-  mrb_assert(is_major_gc(gc));
-  do {
-    mrb_incremental_gc(mrb);
-  } while (gc->state != MRB_GC_STATE_ROOT);
-  mrb_assert(gc->full == FALSE);
-
-  mrb_close(mrb);
-}
-
-void
-test_incremental_sweep_phase(void)
-{
-  mrb_state *mrb = mrb_open();
-  mrb_gc *gc = &mrb->gc;
-
-  puts("test_incremental_sweep_phase");
-
-  add_heap(mrb, gc);
-  gc->sweeps = gc->heaps;
-
-  mrb_assert(gc->heaps->next->next == NULL);
-  mrb_assert(gc->free_heaps->next->next == NULL);
-  incremental_sweep_phase(mrb, gc, MRB_HEAP_PAGE_SIZE * 3);
-
-  mrb_assert(gc->heaps->next == NULL);
-  mrb_assert(gc->heaps == gc->free_heaps);
-
-  mrb_close(mrb);
-}
-
-static mrb_value
-gc_test(mrb_state *mrb, mrb_value self)
-{
-  test_mrb_field_write_barrier();
-  test_mrb_write_barrier();
-  test_add_gray_list();
-  test_gc_gray_mark();
-  test_incremental_gc();
-  test_incremental_sweep_phase();
-  return mrb_nil_value();
-}
-#endif  /* GC_DEBUG */
-#endif  /* GC_TEST */
index fd963c3..d9ee483 100644 (file)
@@ -73,7 +73,7 @@ ht_hash_func(mrb_state *mrb, htable *t, mrb_value key)
 
   default:
     hv = mrb_funcall(mrb, key, "hash", 0);
-    h = (size_t)t ^ (size_t)mrb_fixnum(hv);
+    h = (size_t)tt ^ (size_t)mrb_fixnum(hv);
     break;
   }
   if (index && (index != t->index || capa != index->capa)) {
@@ -92,7 +92,7 @@ ht_hash_equal(mrb_state *mrb, htable *t, mrb_value a, mrb_value b)
     return mrb_str_equal(mrb, a, b);
 
   case MRB_TT_SYMBOL:
-    if (mrb_type(b) != MRB_TT_SYMBOL) return FALSE;
+    if (!mrb_symbol_p(b)) return FALSE;
     return mrb_symbol(a) == mrb_symbol(b);
 
   case MRB_TT_FIXNUM:
@@ -182,7 +182,7 @@ ht_index(mrb_state *mrb, htable *t)
   if (!index || index->capa < size) {
     index = (segindex*)mrb_realloc_simple(mrb, index, sizeof(segindex)+sizeof(struct segkv*)*size);
     if (index == NULL) {
-      mrb_free(mrb, index);
+      mrb_free(mrb, t->index);
       t->index = NULL;
       return;
     }
@@ -222,9 +222,8 @@ static void
 ht_compact(mrb_state *mrb, htable *t)
 {
   segment *seg;
-  mrb_int i;
+  uint16_t i, i2;
   segment *seg2 = NULL;
-  mrb_int i2;
   mrb_int size = 0;
 
   if (t == NULL) return;
@@ -240,7 +239,7 @@ ht_compact(mrb_state *mrb, htable *t)
       if (!seg->next && i >= t->last_len) {
         goto exit;
       }
-      if (mrb_undef_p(k)) {     /* found delete key */
+      if (mrb_undef_p(k)) {     /* found deleted key */
         if (seg2 == NULL) {
           seg2 = seg;
           i2 = i;
@@ -366,7 +365,7 @@ ht_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val)
       if (!seg->next && i >= t->last_len) {
         seg->e[i].key = key;
         seg->e[i].val = val;
-        t->last_len = i+1;
+        t->last_len = (uint16_t)i+1;
         t->size++;
         return;
       }
@@ -374,7 +373,7 @@ ht_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val)
         deleted++;
         continue;
       }
-      if (ht_hash_equal(mrb, t, k, key)) {
+      if (ht_hash_equal(mrb, t, key, k)) {
         seg->e[i].val = val;
         return;
       }
@@ -408,7 +407,7 @@ ht_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val)
   }
   seg->e[i].key = key;
   seg->e[i].val = val;
-  t->last_len = i+1;
+  t->last_len = (uint16_t)i+1;
   if (t->index == NULL && t->size > MRB_HT_INIT_SIZE*4) {
     ht_index(mrb, t);
   }
@@ -455,7 +454,7 @@ ht_get(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
         return FALSE;
       }
       if (mrb_undef_p(k)) continue;
-      if (ht_hash_equal(mrb, t, k, key)) {
+      if (ht_hash_equal(mrb, t, key, k)) {
         if (vp) *vp = seg->e[i].val;
         return TRUE;
       }
@@ -546,6 +545,7 @@ ht_copy(mrb_state *mrb, htable *t)
       if ((seg->next == NULL) && (i >= t->last_len)) {
         return t2;
       }
+      if (mrb_undef_p(key)) continue; /* skip deleted key */
       ht_put(mrb, t2, key, val);
     }
     seg = seg->next;
@@ -575,7 +575,7 @@ static void mrb_hash_modify(mrb_state *mrb, mrb_value hash);
 static inline mrb_value
 ht_key(mrb_state *mrb, mrb_value key)
 {
-  if (mrb_string_p(key) && !MRB_FROZEN_P(mrb_str_ptr(key))) {
+  if (mrb_string_p(key) && !mrb_frozen_p(mrb_str_ptr(key))) {
     key = mrb_str_dup(mrb, key);
     MRB_SET_FROZEN_FLAG(mrb_str_ptr(key));
   }
@@ -641,12 +641,11 @@ static mrb_value hash_default(mrb_state *mrb, mrb_value hash, mrb_value key);
 static mrb_value
 mrb_hash_init_copy(mrb_state *mrb, mrb_value self)
 {
-  mrb_value orig;
+  mrb_value orig = mrb_get_arg1(mrb);
   struct RHash* copy;
   htable *orig_h;
   mrb_value ifnone, vret;
 
-  mrb_get_args(mrb, "o", &orig);
   if (mrb_obj_equal(mrb, self, orig)) return self;
   if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) {
       mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object");
@@ -746,10 +745,7 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val)
 static void
 mrb_hash_modify(mrb_state *mrb, mrb_value hash)
 {
-  if (MRB_FROZEN_P(mrb_hash_ptr(hash))) {
-    mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen hash");
-  }
-
+  mrb_check_frozen(mrb, mrb_hash_ptr(hash));
   if (!RHASH_TBL(hash)) {
     RHASH_TBL(hash) = ht_new(mrb);
   }
@@ -802,7 +798,7 @@ mrb_hash_init(mrb_state *mrb, mrb_value hash)
   mrb_hash_modify(mrb, hash);
   if (!mrb_nil_p(block)) {
     if (ifnone_p) {
-      mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
+      mrb_argnum_error(mrb, 1, 0, 0);
     }
     RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
     ifnone = block;
@@ -831,9 +827,8 @@ mrb_hash_init(mrb_state *mrb, mrb_value hash)
 static mrb_value
 mrb_hash_aget(mrb_state *mrb, mrb_value self)
 {
-  mrb_value key;
+  mrb_value key = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &key);
   return mrb_hash_get(mrb, self, key);
 }
 
@@ -916,9 +911,8 @@ mrb_hash_default(mrb_state *mrb, mrb_value hash)
 static mrb_value
 mrb_hash_set_default(mrb_state *mrb, mrb_value hash)
 {
-  mrb_value ifnone;
+  mrb_value ifnone = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &ifnone);
   mrb_hash_modify(mrb, hash);
   mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
   RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
@@ -972,9 +966,8 @@ mrb_hash_default_proc(mrb_state *mrb, mrb_value hash)
 static mrb_value
 mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
 {
-  mrb_value ifnone;
+  mrb_value ifnone = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &ifnone);
   mrb_hash_modify(mrb, hash);
   mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
   if (!mrb_nil_p(ifnone)) {
@@ -1006,9 +999,8 @@ mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key)
 static mrb_value
 mrb_hash_delete(mrb_state *mrb, mrb_value self)
 {
-  mrb_value key;
+  mrb_value key = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &key);
   mrb_hash_modify(mrb, self);
   return mrb_hash_delete_key(mrb, self, key);
 }
@@ -1291,10 +1283,9 @@ mrb_hash_key_p(mrb_state *mrb, mrb_value hash, mrb_value key)
 static mrb_value
 mrb_hash_has_key(mrb_state *mrb, mrb_value hash)
 {
-  mrb_value key;
+  mrb_value key = mrb_get_arg1(mrb);
   mrb_bool key_p;
 
-  mrb_get_args(mrb, "o", &key);
   key_p = mrb_hash_key_p(mrb, hash, key);
   return mrb_bool_value(key_p);
 }
@@ -1334,10 +1325,9 @@ hash_has_value_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
 static mrb_value
 mrb_hash_has_value(mrb_state *mrb, mrb_value hash)
 {
-  mrb_value val;
+  mrb_value val = mrb_get_arg1(mrb);
   struct has_v_arg arg;
   
-  mrb_get_args(mrb, "o", &val);
   arg.found = FALSE;
   arg.val = val;
   ht_foreach(mrb, RHASH_TBL(hash), hash_has_value_i, &arg);
@@ -1381,10 +1371,21 @@ mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2)
  *  values of key objects have changed since they were inserted, this
  *  method will reindex <i>hsh</i>.
  *
- *     h = {"AAA" => "b"}
- *     h.keys[0].chop!
- *     h.rehash   #=> {"AA"=>"b"}
- *     h["AA"]    #=> "b"
+ *     keys = (1..17).map{|n| [n]}
+ *     k = keys[0]
+ *     h = {}
+ *     keys.each{|key| h[key] = key[0]}
+ *     h     #=> { [1]=> 1, [2]=> 2, [3]=> 3, [4]=> 4, [5]=> 5, [6]=> 6, [7]=> 7,
+ *                 [8]=> 8, [9]=> 9,[10]=>10,[11]=>11,[12]=>12,[13]=>13,[14]=>14,
+ *                [15]=>15,[16]=>16,[17]=>17}
+ *     h[k]  #=> 1
+ *     k[0] = keys.size + 1
+ *     h     #=> {[18]=> 1, [2]=> 2, [3]=> 3, [4]=> 4, [5]=> 5, [6]=> 6, [7]=> 7,
+ *                 [8]=> 8, [9]=> 9,[10]=>10,[11]=>11,[12]=>12,[13]=>13,[14]=>14,
+ *                [15]=>15,[16]=>16,[17]=>17}
+ *     h[k]  #=> nil
+ *     h.rehash
+ *     h[k]  #=> 1
  */
 static mrb_value
 mrb_hash_rehash(mrb_state *mrb, mrb_value self)
@@ -1405,7 +1406,7 @@ mrb_init_hash(mrb_state *mrb)
   mrb_define_method(mrb, h, "[]",              mrb_hash_aget,        MRB_ARGS_REQ(1)); /* 15.2.13.4.2  */
   mrb_define_method(mrb, h, "[]=",             mrb_hash_aset,        MRB_ARGS_REQ(2)); /* 15.2.13.4.3  */
   mrb_define_method(mrb, h, "clear",           mrb_hash_clear,       MRB_ARGS_NONE()); /* 15.2.13.4.4  */
-  mrb_define_method(mrb, h, "default",         mrb_hash_default,     MRB_ARGS_ANY());  /* 15.2.13.4.5  */
+  mrb_define_method(mrb, h, "default",         mrb_hash_default,     MRB_ARGS_OPT(1));  /* 15.2.13.4.5  */
   mrb_define_method(mrb, h, "default=",        mrb_hash_set_default, MRB_ARGS_REQ(1)); /* 15.2.13.4.6  */
   mrb_define_method(mrb, h, "default_proc",    mrb_hash_default_proc,MRB_ARGS_NONE()); /* 15.2.13.4.7  */
   mrb_define_method(mrb, h, "default_proc=",   mrb_hash_set_default_proc,MRB_ARGS_REQ(1)); /* 15.2.13.4.7  */
@@ -1414,7 +1415,7 @@ mrb_init_hash(mrb_state *mrb)
   mrb_define_method(mrb, h, "has_key?",        mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.13 */
   mrb_define_method(mrb, h, "has_value?",      mrb_hash_has_value,   MRB_ARGS_REQ(1)); /* 15.2.13.4.14 */
   mrb_define_method(mrb, h, "include?",        mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.15 */
-  mrb_define_method(mrb, h, "initialize",      mrb_hash_init,        MRB_ARGS_OPT(1)); /* 15.2.13.4.16 */
+  mrb_define_method(mrb, h, "initialize",      mrb_hash_init,        MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); /* 15.2.13.4.16 */
   mrb_define_method(mrb, h, "key?",            mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.18 */
   mrb_define_method(mrb, h, "keys",            mrb_hash_keys,        MRB_ARGS_NONE()); /* 15.2.13.4.19 */
   mrb_define_method(mrb, h, "length",          mrb_hash_size_m,      MRB_ARGS_NONE()); /* 15.2.13.4.20 */
index 7890e3d..8f0c9c7 100644 (file)
@@ -53,7 +53,7 @@ mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj)
 MRB_API mrb_value
 mrb_obj_inspect(mrb_state *mrb, mrb_value obj)
 {
-  if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) {
+  if (mrb_object_p(obj) && mrb_obj_basic_to_s_p(mrb, obj)) {
     return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj));
   }
   return mrb_any_to_s(mrb, obj);
@@ -71,9 +71,8 @@ mrb_obj_inspect(mrb_state *mrb, mrb_value obj)
 static mrb_value
 mrb_equal_m(mrb_state *mrb, mrb_value self)
 {
-  mrb_value arg;
+  mrb_value arg = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &arg);
   return mrb_bool_value(mrb_equal(mrb, self, arg));
 }
 
@@ -161,7 +160,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
     /* use saved block arg position */
     bidx = MRB_ENV_BIDX(e);
     /* bidx may be useless (e.g. define_method) */
-    if (bidx >= MRB_ENV_STACK_LEN(e))
+    if (bidx >= MRB_ENV_LEN(e))
       return mrb_false_value();
     bp = &e->stack[bidx];
   }
@@ -325,9 +324,9 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self)
   mrb_value clone;
 
   if (mrb_immediate_p(self)) {
-    mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self);
+    return self;
   }
-  if (mrb_type(self) == MRB_TT_SCLASS) {
+  if (mrb_sclass_p(self)) {
     mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class");
   }
   p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
@@ -366,9 +365,9 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj)
   mrb_value dup;
 
   if (mrb_immediate_p(obj)) {
-    mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj);
+    return obj;
   }
-  if (mrb_type(obj) == MRB_TT_SCLASS) {
+  if (mrb_sclass_p(obj)) {
     mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class");
   }
   p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
@@ -384,7 +383,7 @@ mrb_obj_extend(mrb_state *mrb, mrb_int argc, mrb_value *argv, mrb_value obj)
   mrb_int i;
 
   if (argc == 0) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (at least 1)");
+    mrb_argnum_error(mrb, argc, 1, -1);
   }
   for (i = 0; i < argc; i++) {
     mrb_check_type(mrb, argv[i], MRB_TT_MODULE);
@@ -431,27 +430,15 @@ mrb_obj_extend_m(mrb_state *mrb, mrb_value self)
   return mrb_obj_extend(mrb, argc, argv, self);
 }
 
-static mrb_value
+MRB_API mrb_value
 mrb_obj_freeze(mrb_state *mrb, mrb_value self)
 {
-  struct RBasic *b;
-
-  switch (mrb_type(self)) {
-    case MRB_TT_FALSE:
-    case MRB_TT_TRUE:
-    case MRB_TT_FIXNUM:
-    case MRB_TT_SYMBOL:
-#ifndef MRB_WITHOUT_FLOAT
-    case MRB_TT_FLOAT:
-#endif
-      return self;
-    default:
-      break;
-  }
-
-  b = mrb_basic_ptr(self);
-  if (!MRB_FROZEN_P(b)) {
-    MRB_SET_FROZEN_FLAG(b);
+  if (!mrb_immediate_p(self)) {
+    struct RBasic *b = mrb_basic_ptr(self);
+    if (!mrb_frozen_p(b)) {
+      MRB_SET_FROZEN_FLAG(b);
+      if (b->c->tt == MRB_TT_SCLASS) MRB_SET_FROZEN_FLAG(b->c);
+    }
   }
   return self;
 }
@@ -459,26 +446,7 @@ mrb_obj_freeze(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_obj_frozen(mrb_state *mrb, mrb_value self)
 {
-  struct RBasic *b;
-
-  switch (mrb_type(self)) {
-    case MRB_TT_FALSE:
-    case MRB_TT_TRUE:
-    case MRB_TT_FIXNUM:
-    case MRB_TT_SYMBOL:
-#ifndef MRB_WITHOUT_FLOAT
-    case MRB_TT_FLOAT:
-#endif
-      return mrb_true_value();
-    default:
-      break;
-  }
-
-  b = mrb_basic_ptr(self);
-  if (!MRB_FROZEN_P(b)) {
-    return mrb_false_value();
-  }
-  return mrb_true_value();
+  return mrb_bool_value(mrb_immediate_p(self) || mrb_frozen_p(mrb_basic_ptr(self)));
 }
 
 /* 15.3.1.3.15 */
@@ -502,9 +470,8 @@ mrb_obj_hash(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_obj_init_copy(mrb_state *mrb, mrb_value self)
 {
-  mrb_value orig;
+  mrb_value orig = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &orig);
   if (mrb_obj_equal(mrb, self, orig)) return self;
   if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) {
       mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object");
@@ -672,7 +639,7 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
   mrb_iv_name_sym_check(mrb, sym);
   val = mrb_iv_remove(mrb, self, sym);
   if (mrb_undef_p(val)) {
-    mrb_name_error(mrb, sym, "instance variable %S not defined", mrb_sym2str(mrb, sym));
+    mrb_name_error(mrb, sym, "instance variable %n not defined", sym);
   }
   return val;
 }
@@ -680,7 +647,7 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
 void
 mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args)
 {
-  mrb_no_method_error(mrb, name, args, "undefined method '%S'", mrb_sym2str(mrb, name));
+  mrb_no_method_error(mrb, name, args, "undefined method '%n'", name);
 }
 
 /* 15.3.1.3.30 */
@@ -716,7 +683,6 @@ mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args)
  *     r.xxiii   #=> 23
  *     r.mm      #=> 2000
  */
-#ifdef MRB_DEFAULT_METHOD_MISSING
 static mrb_value
 mrb_obj_missing(mrb_state *mrb, mrb_value mod)
 {
@@ -729,7 +695,6 @@ mrb_obj_missing(mrb_state *mrb, mrb_value mod)
   /* not reached */
   return mrb_nil_value();
 }
-#endif
 
 static inline mrb_bool
 basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub)
@@ -777,12 +742,11 @@ obj_respond_to(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_obj_ceqq(mrb_state *mrb, mrb_value self)
 {
-  mrb_value v;
+  mrb_value v = mrb_get_arg1(mrb);
   mrb_int i, len;
   mrb_sym eqq = mrb_intern_lit(mrb, "===");
   mrb_value ary = mrb_ary_splat(mrb, self);
 
-  mrb_get_args(mrb, "o", &v);
   len = RARRAY_LEN(ary);
   for (i=0; i<len; i++) {
     mrb_value c = mrb_funcall_argv(mrb, mrb_ary_entry(ary, i), eqq, 1, &v);
@@ -811,11 +775,9 @@ mrb_init_kernel(mrb_state *mrb)
   mrb_define_method(mrb, krn, "clone",                      mrb_obj_clone,                   MRB_ARGS_NONE());    /* 15.3.1.3.8  */
   mrb_define_method(mrb, krn, "dup",                        mrb_obj_dup,                     MRB_ARGS_NONE());    /* 15.3.1.3.9  */
   mrb_define_method(mrb, krn, "eql?",                       mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.10 */
-  mrb_define_method(mrb, krn, "equal?",                     mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.11 */
   mrb_define_method(mrb, krn, "extend",                     mrb_obj_extend_m,                MRB_ARGS_ANY());     /* 15.3.1.3.13 */
   mrb_define_method(mrb, krn, "freeze",                     mrb_obj_freeze,                  MRB_ARGS_NONE());
   mrb_define_method(mrb, krn, "frozen?",                    mrb_obj_frozen,                  MRB_ARGS_NONE());
-  mrb_define_method(mrb, krn, "global_variables",           mrb_f_global_variables,          MRB_ARGS_NONE());    /* 15.3.1.3.14 */
   mrb_define_method(mrb, krn, "hash",                       mrb_obj_hash,                    MRB_ARGS_NONE());    /* 15.3.1.3.15 */
   mrb_define_method(mrb, krn, "initialize_copy",            mrb_obj_init_copy,               MRB_ARGS_REQ(1));    /* 15.3.1.3.16 */
   mrb_define_method(mrb, krn, "inspect",                    mrb_obj_inspect,                 MRB_ARGS_NONE());    /* 15.3.1.3.17 */
@@ -824,19 +786,16 @@ mrb_init_kernel(mrb_state *mrb)
   mrb_define_method(mrb, krn, "is_a?",                      mrb_obj_is_kind_of_m,            MRB_ARGS_REQ(1));    /* 15.3.1.3.24 */
   mrb_define_method(mrb, krn, "iterator?",                  mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.3.25 */
   mrb_define_method(mrb, krn, "kind_of?",                   mrb_obj_is_kind_of_m,            MRB_ARGS_REQ(1));    /* 15.3.1.3.26 */
-#ifdef MRB_DEFAULT_METHOD_MISSING
   mrb_define_method(mrb, krn, "method_missing",             mrb_obj_missing,                 MRB_ARGS_ANY());     /* 15.3.1.3.30 */
-#endif
   mrb_define_method(mrb, krn, "nil?",                       mrb_false,                       MRB_ARGS_NONE());    /* 15.3.1.3.32 */
   mrb_define_method(mrb, krn, "object_id",                  mrb_obj_id_m,                    MRB_ARGS_NONE());    /* 15.3.1.3.33 */
   mrb_define_method(mrb, krn, "raise",                      mrb_f_raise,                     MRB_ARGS_ANY());     /* 15.3.1.3.40 */
   mrb_define_method(mrb, krn, "remove_instance_variable",   mrb_obj_remove_instance_variable,MRB_ARGS_REQ(1));    /* 15.3.1.3.41 */
-  mrb_define_method(mrb, krn, "respond_to?",                obj_respond_to,                  MRB_ARGS_ANY());     /* 15.3.1.3.43 */
+  mrb_define_method(mrb, krn, "respond_to?",                obj_respond_to,                  MRB_ARGS_ARG(1,1));     /* 15.3.1.3.43 */
   mrb_define_method(mrb, krn, "to_s",                       mrb_any_to_s,                    MRB_ARGS_NONE());    /* 15.3.1.3.46 */
   mrb_define_method(mrb, krn, "__case_eqq",                 mrb_obj_ceqq,                    MRB_ARGS_REQ(1));    /* internal */
   mrb_define_method(mrb, krn, "__to_int",                   mrb_to_int,                      MRB_ARGS_NONE()); /* internal */
   mrb_define_method(mrb, krn, "__to_str",                   mrb_to_str,                      MRB_ARGS_NONE()); /* internal */
 
   mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
-  mrb_define_alias(mrb, mrb->module_class, "dup", "clone"); /* XXX */
 }
index ab03467..3077859 100644 (file)
 #include <mruby/string.h>
 #include <mruby/debug.h>
 #include <mruby/error.h>
+#include <mruby/data.h>
 
 #if SIZE_MAX < UINT32_MAX
 # error size_t must be at least 32 bits wide
 #endif
 
-#define FLAG_BYTEORDER_BIG 2
-#define FLAG_BYTEORDER_LIL 4
-#define FLAG_BYTEORDER_NATIVE 8
 #define FLAG_SRC_MALLOC 1
 #define FLAG_SRC_STATIC 0
 
@@ -42,22 +40,30 @@ offset_crc_body(void)
 }
 
 #ifndef MRB_WITHOUT_FLOAT
+double mrb_str_len_to_dbl(mrb_state *mrb, const char *s, size_t len, mrb_bool badcheck);
+
 static double
-str_to_double(mrb_state *mrb, mrb_value str)
+str_to_double(mrb_state *mrb, const char *p, size_t len)
 {
-  const char *p = RSTRING_PTR(str);
-  mrb_int len = RSTRING_LEN(str);
-
   /* `i`, `inf`, `infinity` */
   if (len > 0 && p[0] == 'i') return INFINITY;
 
   /* `I`, `-inf`, `-infinity` */
   if (p[0] == 'I' || (len > 1 && p[0] == '-' && p[1] == 'i')) return -INFINITY;
-
-  return mrb_str_to_dbl(mrb, str, TRUE);
+  return mrb_str_len_to_dbl(mrb, p, len, TRUE);
 }
 #endif
 
+mrb_value mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base, int badcheck);
+
+static void
+tempirep_free(mrb_state *mrb, void *p)
+{
+  if (p) mrb_irep_decref(mrb, (mrb_irep *)p);
+}
+
+static const mrb_data_type tempirep_type = { "temporary irep", tempirep_free };
+
 static mrb_irep*
 read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
 {
@@ -66,8 +72,11 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
   ptrdiff_t diff;
   uint16_t tt, pool_data_len, snl;
   int plen;
-  int ai = mrb_gc_arena_save(mrb);
+  struct RData *irep_obj = mrb_data_object_alloc(mrb, mrb->object_class, NULL, &tempirep_type);
   mrb_irep *irep = mrb_add_irep(mrb);
+  int ai = mrb_gc_arena_save(mrb);
+
+  irep_obj->data = irep;
 
   /* skip record size */
   src += sizeof(uint32_t);
@@ -94,16 +103,16 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
     if (SIZE_ERROR_MUL(irep->ilen, sizeof(mrb_code))) {
       return NULL;
     }
-    if ((flags & FLAG_SRC_MALLOC) == 0 &&
-        (flags & FLAG_BYTEORDER_NATIVE)) {
+    if ((flags & FLAG_SRC_MALLOC) == 0) {
       irep->iseq = (mrb_code*)src;
       src += sizeof(mrb_code) * irep->ilen;
       irep->flags |= MRB_ISEQ_NO_FREE;
     }
     else {
       size_t data_len = sizeof(mrb_code) * irep->ilen;
-      irep->iseq = (mrb_code *)mrb_malloc(mrb, data_len);
-      memcpy(irep->iseq, src, data_len);
+      void *buf = mrb_malloc(mrb, data_len);
+      irep->iseq = (mrb_code *)buf;
+      memcpy(buf, src, data_len);
       src += data_len;
     }
   }
@@ -118,21 +127,17 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
     irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * plen);
 
     for (i = 0; i < plen; i++) {
-      mrb_value s;
+      const char *s;
+      mrb_bool st = (flags & FLAG_SRC_MALLOC)==0;
 
       tt = *src++; /* pool TT */
       pool_data_len = bin_to_uint16(src); /* pool data length */
       src += sizeof(uint16_t);
-      if (flags & FLAG_SRC_MALLOC) {
-        s = mrb_str_new(mrb, (char *)src, pool_data_len);
-      }
-      else {
-        s = mrb_str_new_static(mrb, (char *)src, pool_data_len);
-      }
+      s = (const char*)src;
       src += pool_data_len;
       switch (tt) { /* pool data */
       case IREP_TT_FIXNUM: {
-        mrb_value num = mrb_str_to_inum(mrb, s, 10, FALSE);
+        mrb_value num = mrb_str_len_to_inum(mrb, s, pool_data_len, 10, FALSE);
 #ifdef MRB_WITHOUT_FLOAT
         irep->pool[i] = num;
 #else
@@ -143,12 +148,12 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
 
 #ifndef MRB_WITHOUT_FLOAT
       case IREP_TT_FLOAT:
-        irep->pool[i] = mrb_float_pool(mrb, str_to_double(mrb, s));
+        irep->pool[i] = mrb_float_pool(mrb, str_to_double(mrb, s, pool_data_len));
         break;
 #endif
 
       case IREP_TT_STRING:
-        irep->pool[i] = mrb_str_pool(mrb, s);
+        irep->pool[i] = mrb_str_pool(mrb, s, pool_data_len, st);
         break;
 
       default:
@@ -191,36 +196,47 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
     }
   }
 
-  irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*irep->rlen);
+  irep->reps = (mrb_irep**)mrb_calloc(mrb, irep->rlen, sizeof(mrb_irep*));
 
   diff = src - bin;
   mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
   *len = (size_t)diff;
 
+  irep_obj->data = NULL;
+
   return irep;
 }
 
 static mrb_irep*
 read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
 {
+  struct RData *irep_obj = mrb_data_object_alloc(mrb, mrb->object_class, NULL, &tempirep_type);
+  int ai = mrb_gc_arena_save(mrb);
   mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags);
   int i;
 
+  mrb_gc_arena_restore(mrb, ai);
   if (irep == NULL) {
     return NULL;
   }
 
+  irep_obj->data = irep;
+
   bin += *len;
   for (i=0; i<irep->rlen; i++) {
     size_t rlen;
 
     irep->reps[i] = read_irep_record(mrb, bin, &rlen, flags);
+    mrb_gc_arena_restore(mrb, ai);
     if (irep->reps[i] == NULL) {
       return NULL;
     }
     bin += rlen;
     *len += rlen;
   }
+
+  irep_obj->data = NULL;
+
   return irep;
 }
 
@@ -233,66 +249,6 @@ read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
   return read_irep_record(mrb, bin, &len, flags);
 }
 
-/* ignore lineno record */
-static int
-read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *len)
-{
-  size_t i, fname_len, niseq;
-
-  *len = 0;
-  bin += sizeof(uint32_t); /* record size */
-  *len += sizeof(uint32_t);
-  fname_len = bin_to_uint16(bin);
-  bin += sizeof(uint16_t);
-  *len += sizeof(uint16_t);
-  bin += fname_len;
-  *len += fname_len;
-
-  niseq = (size_t)bin_to_uint32(bin);
-  bin += sizeof(uint32_t); /* niseq */
-  *len += sizeof(uint32_t);
-
-  if (SIZE_ERROR_MUL(niseq, sizeof(uint16_t))) {
-    return MRB_DUMP_GENERAL_FAILURE;
-  }
-  for (i = 0; i < niseq; i++) {
-    bin += sizeof(uint16_t); /* niseq */
-    *len += sizeof(uint16_t);
-  }
-
-  return MRB_DUMP_OK;
-}
-
-static int
-read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *lenp)
-{
-  int result = read_lineno_record_1(mrb, bin, irep, lenp);
-  int i;
-
-  if (result != MRB_DUMP_OK) return result;
-  for (i = 0; i < irep->rlen; i++) {
-    size_t len;
-
-    result = read_lineno_record(mrb, bin, irep->reps[i], &len);
-    if (result != MRB_DUMP_OK) break;
-    bin += len;
-    *lenp += len;
-  }
-  return result;
-}
-
-static int
-read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep)
-{
-  size_t len;
-
-  len = 0;
-  bin += sizeof(struct rite_section_lineno_header);
-
-  /* Read Binary Data Section */
-  return read_lineno_record(mrb, bin, irep, &len);
-}
-
 static int
 read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len)
 {
@@ -304,21 +260,21 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
 
   if (irep->debug_info) { return MRB_DUMP_INVALID_IREP; }
 
-  irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info));
+  irep->debug_info = (mrb_irep_debug_info*)mrb_calloc(mrb, 1, sizeof(mrb_irep_debug_info));
   irep->debug_info->pc_count = (uint32_t)irep->ilen;
 
   record_size = (size_t)bin_to_uint32(bin);
   bin += sizeof(uint32_t);
 
   irep->debug_info->flen = bin_to_uint16(bin);
-  irep->debug_info->files = (mrb_irep_debug_info_file**)mrb_malloc(mrb, sizeof(mrb_irep_debug_info*) * irep->debug_info->flen);
+  irep->debug_info->files = (mrb_irep_debug_info_file**)mrb_calloc(mrb, irep->debug_info->flen, sizeof(mrb_irep_debug_info*));
   bin += sizeof(uint16_t);
 
   for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
     mrb_irep_debug_info_file *file;
     uint16_t filename_idx;
 
-    file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file));
+    file = (mrb_irep_debug_info_file *)mrb_calloc(mrb, 1, sizeof(*file));
     irep->debug_info->files[f_idx] = file;
 
     file->start_pos = bin_to_uint32(bin);
@@ -348,8 +304,8 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
       case mrb_debug_line_flat_map: {
         uint32_t l;
 
-        file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(
-            mrb, sizeof(mrb_irep_debug_info_line) * (size_t)(file->line_entry_count));
+        file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_calloc(
+            mrb, (size_t)(file->line_entry_count), sizeof(mrb_irep_debug_info_line));
         for (l = 0; l < file->line_entry_count; ++l) {
           file->lines.flat_map[l].start_pos = bin_to_uint32(bin);
           bin += sizeof(uint32_t);
@@ -396,6 +352,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t
   int result;
   uint16_t filenames_len;
   mrb_sym *filenames;
+  mrb_value filenames_obj;
 
   bin = start;
   header = (struct rite_section_debug_header *)bin;
@@ -403,7 +360,8 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t
 
   filenames_len = bin_to_uint16(bin);
   bin += sizeof(uint16_t);
-  filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)filenames_len);
+  filenames_obj = mrb_str_new(mrb, NULL, sizeof(mrb_sym) * (size_t)filenames_len);
+  filenames = (mrb_sym*)RSTRING_PTR(filenames_obj);
   for (i = 0; i < filenames_len; ++i) {
     uint16_t f_len = bin_to_uint16(bin);
     bin += sizeof(uint16_t);
@@ -427,7 +385,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t
   }
 
 debug_exit:
-  mrb_free(mrb, filenames);
+  mrb_str_resize(mrb, filenames_obj, 0);
   return result;
 }
 
@@ -485,6 +443,7 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t fl
   int result;
   uint32_t syms_len;
   mrb_sym *syms;
+  mrb_value syms_obj;
   mrb_sym (*intern_func)(mrb_state*, const char*, size_t) =
     (flags & FLAG_SRC_MALLOC)? mrb_intern : mrb_intern_static;
 
@@ -494,7 +453,8 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t fl
 
   syms_len = bin_to_uint32(bin);
   bin += sizeof(uint32_t);
-  syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)syms_len);
+  syms_obj = mrb_str_new(mrb, NULL, sizeof(mrb_sym) * (size_t)syms_len);
+  syms = (mrb_sym*)RSTRING_PTR(syms_obj);
   for (i = 0; i < syms_len; ++i) {
     uint16_t const str_len = bin_to_uint16(bin);
     bin += sizeof(uint16_t);
@@ -514,28 +474,24 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t fl
   }
 
 lv_exit:
-  mrb_free(mrb, syms);
+  mrb_str_resize(mrb, syms_obj, 0);
   return result;
 }
 
 static int
-read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t *flags)
+read_binary_header(const uint8_t *bin, size_t bufsize, size_t *bin_size, uint16_t *crc, uint8_t *flags)
 {
   const struct rite_binary_header *header = (const struct rite_binary_header *)bin;
 
-  if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) == 0) {
-    if (bigendian_p())
-      *flags |= FLAG_BYTEORDER_NATIVE;
-    else
-      *flags |= FLAG_BYTEORDER_BIG;
+  if (bufsize < sizeof(struct rite_binary_header)) {
+    return MRB_DUMP_READ_FAULT;
   }
-  else if (memcmp(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)) == 0) {
-    if (bigendian_p())
-      *flags |= FLAG_BYTEORDER_LIL;
-    else
-      *flags |= FLAG_BYTEORDER_NATIVE;
+
+  if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) != 0) {
+    return MRB_DUMP_INVALID_FILE_HEADER;
   }
-  else {
+
+  if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) {
     return MRB_DUMP_INVALID_FILE_HEADER;
   }
 
@@ -544,13 +500,18 @@ read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t
   }
   *bin_size = (size_t)bin_to_uint32(header->binary_size);
 
+  if (bufsize < *bin_size) {
+    return MRB_DUMP_READ_FAULT;
+  }
+
   return MRB_DUMP_OK;
 }
 
 static mrb_irep*
-read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
+read_irep(mrb_state *mrb, const uint8_t *bin, size_t bufsize, uint8_t flags)
 {
   int result;
+  struct RData *irep_obj = NULL;
   mrb_irep *irep = NULL;
   const struct rite_section_header *section_header;
   uint16_t crc;
@@ -561,7 +522,7 @@ read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
     return NULL;
   }
 
-  result = read_binary_header(bin, &bin_size, &crc, &flags);
+  result = read_binary_header(bin, bufsize, &bin_size, &crc, &flags);
   if (result != MRB_DUMP_OK) {
     return NULL;
   }
@@ -571,19 +532,15 @@ read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
     return NULL;
   }
 
+  irep_obj = mrb_data_object_alloc(mrb, mrb->object_class, NULL, &tempirep_type);
+
   bin += sizeof(struct rite_binary_header);
   do {
     section_header = (const struct rite_section_header *)bin;
     if (memcmp(section_header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(section_header->section_ident)) == 0) {
       irep = read_section_irep(mrb, bin, flags);
       if (!irep) return NULL;
-    }
-    else if (memcmp(section_header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(section_header->section_ident)) == 0) {
-      if (!irep) return NULL;   /* corrupted data */
-      result = read_section_lineno(mrb, bin, irep);
-      if (result < MRB_DUMP_OK) {
-        return NULL;
-      }
+      irep_obj->data = irep;
     }
     else if (memcmp(section_header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(section_header->section_ident)) == 0) {
       if (!irep) return NULL;   /* corrupted data */
@@ -602,19 +559,27 @@ read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
     bin += bin_to_uint32(section_header->section_size);
   } while (memcmp(section_header->section_ident, RITE_BINARY_EOF, sizeof(section_header->section_ident)) != 0);
 
+  irep_obj->data = NULL;
+
   return irep;
 }
 
 mrb_irep*
 mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
 {
-#ifdef MRB_USE_ETEXT_EDATA
+#if defined(MRB_USE_LINK_TIME_RO_DATA_P) || defined(MRB_USE_CUSTOM_RO_DATA_P)
   uint8_t flags = mrb_ro_data_p((char*)bin) ? FLAG_SRC_STATIC : FLAG_SRC_MALLOC;
 #else
   uint8_t flags = FLAG_SRC_STATIC;
 #endif
 
-  return read_irep(mrb, bin, flags);
+  return read_irep(mrb, bin, (size_t)-1, flags);
+}
+
+MRB_API mrb_irep*
+mrb_read_irep_buf(mrb_state *mrb, const void *buf, size_t bufsize)
+{
+  return read_irep(mrb, (const uint8_t *)buf, bufsize, FLAG_SRC_MALLOC);
 }
 
 void mrb_exc_set(mrb_state *mrb, mrb_value exc);
@@ -647,7 +612,22 @@ load_irep(mrb_state *mrb, mrb_irep *irep, mrbc_context *c)
 MRB_API mrb_value
 mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c)
 {
-  return load_irep(mrb, mrb_read_irep(mrb, bin), c);
+  struct RData *irep_obj = mrb_data_object_alloc(mrb, mrb->object_class, NULL, &tempirep_type);
+  mrb_irep *irep = mrb_read_irep(mrb, bin);
+  mrb_value ret;
+
+  irep_obj->data = irep;
+  mrb_irep_incref(mrb, irep);
+  ret = load_irep(mrb, irep, c);
+  irep_obj->data = NULL;
+  mrb_irep_decref(mrb, irep);
+  return ret;
+}
+
+MRB_API mrb_value
+mrb_load_irep_buf_cxt(mrb_state *mrb, const void *buf, size_t bufsize, mrbc_context *c)
+{
+  return load_irep(mrb, mrb_read_irep_buf(mrb, buf, bufsize), c);
 }
 
 MRB_API mrb_value
@@ -656,6 +636,12 @@ mrb_load_irep(mrb_state *mrb, const uint8_t *bin)
   return mrb_load_irep_cxt(mrb, bin, NULL);
 }
 
+MRB_API mrb_value
+mrb_load_irep_buf(mrb_state *mrb, const void *buf, size_t bufsize)
+{
+  return mrb_load_irep_buf_cxt(mrb, buf, bufsize, NULL);
+}
+
 #ifndef MRB_DISABLE_STDIO
 
 mrb_irep*
@@ -676,7 +662,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
   if (fread(buf, header_size, 1, fp) == 0) {
     goto irep_exit;
   }
-  result = read_binary_header(buf, &buf_size, NULL, &flags);
+  result = read_binary_header(buf, (size_t)-1, &buf_size, NULL, &flags);
   if (result != MRB_DUMP_OK || buf_size <= header_size) {
     goto irep_exit;
   }
@@ -685,7 +671,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
   if (fread(buf+header_size, buf_size-header_size, 1, fp) == 0) {
     goto irep_exit;
   }
-  irep = read_irep(mrb, buf, FLAG_SRC_MALLOC);
+  irep = read_irep(mrb, buf, (size_t)-1, FLAG_SRC_MALLOC);
 
 irep_exit:
   mrb_free(mrb, buf);
index 4128ea3..49d30c1 100644 (file)
@@ -44,6 +44,15 @@ mrb_to_flo(mrb_state *mrb, mrb_value val)
   }
   return mrb_float(val);
 }
+
+MRB_API mrb_value
+mrb_int_value(mrb_state *mrb, mrb_float f)
+{
+  if (FIXABLE_FLOAT(f)) {
+    return mrb_fixnum_value((mrb_int)f);
+  }
+  return mrb_float_value(mrb, f);
+}
 #endif
 
 /*
@@ -56,14 +65,13 @@ mrb_to_flo(mrb_state *mrb, mrb_value val)
  *    2.0**3      #=> 8.0
  */
 static mrb_value
-num_pow(mrb_state *mrb, mrb_value x)
+integral_pow(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 #ifndef MRB_WITHOUT_FLOAT
   mrb_float d;
 #endif
 
-  mrb_get_args(mrb, "o", &y);
   if (mrb_fixnum_p(x) && mrb_fixnum_p(y)) {
     /* try ipow() */
     mrb_int base = mrb_fixnum(x);
@@ -103,6 +111,24 @@ num_pow(mrb_state *mrb, mrb_value x)
 #endif
 }
 
+static mrb_value
+integral_idiv(mrb_state *mrb, mrb_value x)
+{
+#ifdef MRB_WITHOUT_FLOAT
+  mrb_value y = mrb_get_arg1(mrb);
+
+  if (!mrb_fixnum_p(y)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
+  }
+  return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y));
+#else
+  mrb_float y;
+
+  mrb_get_args(mrb, "f", &y);
+  return mrb_int_value(mrb, mrb_to_flo(mrb, x) / y);
+#endif
+}
+
 /* 15.2.8.3.4  */
 /* 15.2.9.3.4  */
 /*
@@ -114,19 +140,6 @@ num_pow(mrb_state *mrb, mrb_value x)
  * result.
  */
 
-mrb_value
-mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)
-{
-#ifdef MRB_WITHOUT_FLOAT
-  if (!mrb_fixnum_p(y)) {
-    mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
-  }
-  return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y));
-#else
-  return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));
-#endif
-}
-
 /* 15.2.9.3.19(x) */
 /*
  *  call-seq:
@@ -136,12 +149,11 @@ mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)
  */
 
 static mrb_value
-num_div(mrb_state *mrb, mrb_value x)
+integral_div(mrb_state *mrb, mrb_value x)
 {
 #ifdef MRB_WITHOUT_FLOAT
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
   if (!mrb_fixnum_p(y)) {
     mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
   }
@@ -155,19 +167,19 @@ num_div(mrb_state *mrb, mrb_value x)
 }
 
 static mrb_value
-num_coerce_step_counter(mrb_state *mrb, mrb_value self)
+integral_coerce_step_counter(mrb_state *mrb, mrb_value self)
 {
-  mrb_value counter = self, num, step;
+  mrb_value num, step;
 
   mrb_get_args(mrb, "oo", &num, &step);
 
 #ifndef MRB_WITHOUT_FLOAT
   if (mrb_float_p(self) || mrb_float_p(num) || mrb_float_p(step)) {
-    counter = mrb_funcall(mrb, counter, "to_f", 0);
+    return mrb_Float(mrb, self);
   }
 #endif
 
-  return counter;
+  return self;
 }
 
 #ifndef MRB_WITHOUT_FLOAT
@@ -195,26 +207,30 @@ static mrb_value
 flo_to_s(mrb_state *mrb, mrb_value flt)
 {
   mrb_float f = mrb_float(flt);
+  mrb_value str;
 
   if (isinf(f)) {
-    return f < 0 ? mrb_str_new_lit(mrb, "-Infinity")
-                 : mrb_str_new_lit(mrb, "Infinity");
+    str = f < 0 ? mrb_str_new_lit(mrb, "-Infinity")
+                : mrb_str_new_lit(mrb, "Infinity");
+    goto exit;
   }
   else if (isnan(f)) {
-    return mrb_str_new_lit(mrb, "NaN");
+    str = mrb_str_new_lit(mrb, "NaN");
+    goto exit;
   }
   else {
     char fmt[] = "%." MRB_STRINGIZE(FLO_TO_STR_PREC) "g";
-    mrb_value str = mrb_float_to_str(mrb, flt, fmt);
     mrb_int len;
-    char *begp;
+    char *begp, *p, *endp;
+
+    str = mrb_float_to_str(mrb, flt, fmt);
 
     insert_dot_zero:
     begp = RSTRING_PTR(str);
     len = RSTRING_LEN(str);
-    for (char *p = begp, *endp = p + len; p < endp; ++p) {
+    for (p = begp, endp = p + len; p < endp; ++p) {
       if (*p == '.') {
-        return str;
+        goto exit;
       }
       else if (*p == 'e') {
         ptrdiff_t e_pos = p - begp;
@@ -222,7 +238,7 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
         p = RSTRING_PTR(str) + e_pos;
         memmove(p + 2, p, len - e_pos);
         memcpy(p, ".0", 2);
-        return str;
+        goto exit;
       }
     }
 
@@ -231,12 +247,13 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
       str = mrb_float_to_str(mrb, flt, fmt);
       goto insert_dot_zero;
     }
-    else {
-      mrb_str_cat(mrb, str, ".0", 2);
-    }
 
-    return str;
+    goto exit;
   }
+
+  exit:
+  RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+  return str;
 }
 
 /* 15.2.9.3.2  */
@@ -251,9 +268,8 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
 static mrb_value
 flo_minus(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
   return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y));
 }
 
@@ -269,9 +285,8 @@ flo_minus(mrb_state *mrb, mrb_value x)
 static mrb_value
 flo_mul(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
   return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y));
 }
 
@@ -305,6 +320,8 @@ flodivmod(mrb_state *mrb, double x, double y, mrb_float *divp, mrb_float *modp)
     div = (x - mod) / y;
     if (modp && divp) div = round(div);
   }
+  if (div == 0) div = 0.0;
+  if (mod == 0) mod = 0.0;
   if (y*mod < 0) {
     mod += y;
     div -= 1.0;
@@ -329,11 +346,9 @@ flodivmod(mrb_state *mrb, double x, double y, mrb_float *divp, mrb_float *modp)
 static mrb_value
 flo_mod(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
   mrb_float mod;
 
-  mrb_get_args(mrb, "o", &y);
-
   flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), 0, &mod);
   return mrb_float_value(mrb, mod);
 }
@@ -354,9 +369,8 @@ flo_mod(mrb_state *mrb, mrb_value x)
 static mrb_value
 fix_eql(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
   if (!mrb_fixnum_p(y)) return mrb_false_value();
   return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
 }
@@ -365,9 +379,8 @@ fix_eql(mrb_state *mrb, mrb_value x)
 static mrb_value
 flo_eql(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
   if (!mrb_float_p(y)) return mrb_false_value();
   return mrb_bool_value(mrb_float(x) == mrb_float(y));
 }
@@ -388,8 +401,7 @@ flo_eql(mrb_state *mrb, mrb_value x)
 static mrb_value
 flo_eq(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
-  mrb_get_args(mrb, "o", &y);
+  mrb_value y = mrb_get_arg1(mrb);
 
   switch (mrb_type(y)) {
   case MRB_TT_FIXNUM:
@@ -407,7 +419,6 @@ value_int64(mrb_state *mrb, mrb_value x)
   switch (mrb_type(x)) {
   case MRB_TT_FIXNUM:
     return (int64_t)mrb_fixnum(x);
-    break;
   case MRB_TT_FLOAT:
     return (int64_t)mrb_float(x);
   default:
@@ -421,7 +432,7 @@ value_int64(mrb_state *mrb, mrb_value x)
 static mrb_value
 int64_value(mrb_state *mrb, int64_t v)
 {
-  if (FIXABLE(v)) {
+  if (TYPED_FIXABLE(v,int64_t)) {
     return mrb_fixnum_value((mrb_int)v);
   }
   return mrb_float_value(mrb, (mrb_float)v);
@@ -431,7 +442,6 @@ static mrb_value
 flo_rev(mrb_state *mrb, mrb_value x)
 {
   int64_t v1;
-  mrb_get_args(mrb, "");
   v1 = (int64_t)mrb_float(x);
   return int64_value(mrb, ~v1);
 }
@@ -439,9 +449,8 @@ flo_rev(mrb_state *mrb, mrb_value x)
 static mrb_value
 flo_and(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
   int64_t v1, v2;
-  mrb_get_args(mrb, "o", &y);
 
   v1 = (int64_t)mrb_float(x);
   v2 = value_int64(mrb, y);
@@ -451,9 +460,8 @@ flo_and(mrb_state *mrb, mrb_value x)
 static mrb_value
 flo_or(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
   int64_t v1, v2;
-  mrb_get_args(mrb, "o", &y);
 
   v1 = (int64_t)mrb_float(x);
   v2 = value_int64(mrb, y);
@@ -463,9 +471,8 @@ flo_or(mrb_state *mrb, mrb_value x)
 static mrb_value
 flo_xor(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
   int64_t v1, v2;
-  mrb_get_args(mrb, "o", &y);
 
   v1 = (int64_t)mrb_float(x);
   v2 = value_int64(mrb, y);
@@ -484,6 +491,10 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width)
   if (width < 0) {
     while (width++) {
       val /= 2;
+      if (val < 1.0) {
+        val = 0;
+        break;
+      }
     }
 #if defined(_ISOC99_SOURCE)
     val = trunc(val);
@@ -503,14 +514,11 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width)
       val *= 2;
     }
   }
-  if (FIXABLE_FLOAT(val)) {
-    return mrb_fixnum_value((mrb_int)val);
-  }
-  return mrb_float_value(mrb, val);
+  return mrb_int_value(mrb, val);
 }
 
 static mrb_value
-flo_lshift(mrb_state *mrb, mrb_value x)
+flo_rshift(mrb_state *mrb, mrb_value x)
 {
   mrb_int width;
 
@@ -519,7 +527,7 @@ flo_lshift(mrb_state *mrb, mrb_value x)
 }
 
 static mrb_value
-flo_rshift(mrb_state *mrb, mrb_value x)
+flo_lshift(mrb_state *mrb, mrb_value x)
 {
   mrb_int width;
 
@@ -612,10 +620,7 @@ flo_floor(mrb_state *mrb, mrb_value num)
   mrb_float f = floor(mrb_float(num));
 
   mrb_check_num_exact(mrb, f);
-  if (!FIXABLE_FLOAT(f)) {
-    return mrb_float_value(mrb, f);
-  }
-  return mrb_fixnum_value((mrb_int)f);
+  return mrb_int_value(mrb, f);
 }
 
 /* 15.2.9.3.8  */
@@ -638,10 +643,7 @@ flo_ceil(mrb_state *mrb, mrb_value num)
   mrb_float f = ceil(mrb_float(num));
 
   mrb_check_num_exact(mrb, f);
-  if (!FIXABLE_FLOAT(f)) {
-    return mrb_float_value(mrb, f);
-  }
-  return mrb_fixnum_value((mrb_int)f);
+  return mrb_int_value(mrb, f);
 }
 
 /* 15.2.9.3.12 */
@@ -692,6 +694,7 @@ flo_round(mrb_state *mrb, mrb_value num)
 
   f = 1.0;
   i = ndigits >= 0 ? ndigits : -ndigits;
+  if (ndigits > DBL_DIG+2) return num;
   while  (--i >= 0)
     f = f*10.0;
 
@@ -722,7 +725,7 @@ flo_round(mrb_state *mrb, mrb_value num)
     if (!isfinite(number)) return num;
     return mrb_float_value(mrb, number);
   }
-  return mrb_fixnum_value((mrb_int)number);
+  return mrb_int_value(mrb, number);
 }
 
 /* 15.2.9.3.14 */
@@ -744,10 +747,7 @@ flo_truncate(mrb_state *mrb, mrb_value num)
   if (f < 0.0) f = ceil(f);
 
   mrb_check_num_exact(mrb, f);
-  if (!FIXABLE_FLOAT(f)) {
-    return mrb_float_value(mrb, f);
-  }
-  return mrb_fixnum_value((mrb_int)f);
+  return mrb_int_value(mrb, f);
 }
 
 static mrb_value
@@ -780,8 +780,8 @@ int_to_i(mrb_state *mrb, mrb_value num)
   return num;
 }
 
-mrb_value
-mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
+static mrb_value
+fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
 {
   mrb_int a;
 
@@ -805,6 +805,21 @@ mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
 #endif
 }
 
+MRB_API mrb_value
+mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y)
+{
+  if (mrb_fixnum_p(x)) {
+    return fixnum_mul(mrb, x, y);
+  }
+#ifndef MRB_WITHOUT_FLOAT
+  if (mrb_float_p(x)) {
+    return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y));
+  }
+#endif
+  mrb_raise(mrb, E_TYPE_ERROR, "no number multiply");
+  return mrb_nil_value();       /* not reached */
+}
+
 /* 15.2.8.3.3  */
 /*
  * call-seq:
@@ -818,10 +833,9 @@ mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
 static mrb_value
 fix_mul(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
-  return mrb_fixnum_mul(mrb, x, y);
+  return fixnum_mul(mrb, x, y);
 }
 
 static void
@@ -865,23 +879,24 @@ fixdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp)
 static mrb_value
 fix_mod(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
-  mrb_int a;
+  mrb_value y = mrb_get_arg1(mrb);
+  mrb_int a, b;
 
-  mrb_get_args(mrb, "o", &y);
   a = mrb_fixnum(x);
-  if (mrb_fixnum_p(y)) {
-    mrb_int b, mod;
+   if (mrb_fixnum_p(y) && a != MRB_INT_MIN && (b=mrb_fixnum(y)) != MRB_INT_MIN) {
+    mrb_int mod;
 
-    if ((b=mrb_fixnum(y)) == 0) {
+    if (b == 0) {
 #ifdef MRB_WITHOUT_FLOAT
       /* ZeroDivisionError */
       return mrb_fixnum_value(0);
 #else
+      if (a > 0) return mrb_float_value(mrb, INFINITY);
+      if (a < 0) return mrb_float_value(mrb, INFINITY);
       return mrb_float_value(mrb, NAN);
 #endif
     }
-    fixdivmod(mrb, a, b, 0, &mod);
+    fixdivmod(mrb, a, b, NULL, &mod);
     return mrb_fixnum_value(mod);
   }
 #ifdef MRB_WITHOUT_FLOAT
@@ -890,7 +905,7 @@ fix_mod(mrb_state *mrb, mrb_value x)
   else {
     mrb_float mod;
 
-    flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod);
+    flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), NULL, &mod);
     return mrb_float_value(mrb, mod);
   }
 #endif
@@ -905,9 +920,7 @@ fix_mod(mrb_state *mrb, mrb_value x)
 static mrb_value
 fix_divmod(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
-
-  mrb_get_args(mrb, "o", &y);
+  mrb_value y = mrb_get_arg1(mrb);
 
   if (mrb_fixnum_p(y)) {
     mrb_int div, mod;
@@ -933,7 +946,7 @@ fix_divmod(mrb_state *mrb, mrb_value x)
     mrb_value a, b;
 
     flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod);
-    a = mrb_float_value(mrb, div);
+    a = mrb_int_value(mrb, div);
     b = mrb_float_value(mrb, mod);
     return mrb_assoc_new(mrb, a, b);
   }
@@ -944,14 +957,12 @@ fix_divmod(mrb_state *mrb, mrb_value x)
 static mrb_value
 flo_divmod(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
   mrb_float div, mod;
   mrb_value a, b;
 
-  mrb_get_args(mrb, "o", &y);
-
   flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod);
-  a = mrb_float_value(mrb, div);
+  a = mrb_int_value(mrb, div);
   b = mrb_float_value(mrb, mod);
   return mrb_assoc_new(mrb, a, b);
 }
@@ -972,9 +983,8 @@ flo_divmod(mrb_state *mrb, mrb_value x)
 static mrb_value
 fix_equal(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
   switch (mrb_type(y)) {
   case MRB_TT_FIXNUM:
     return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
@@ -1031,9 +1041,8 @@ static mrb_value flo_xor(mrb_state *mrb, mrb_value x);
 static mrb_value
 fix_and(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
   bit_op(x, y, and, &);
 }
 
@@ -1048,9 +1057,8 @@ fix_and(mrb_state *mrb, mrb_value x)
 static mrb_value
 fix_or(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
   bit_op(x, y, or, |);
 }
 
@@ -1065,9 +1073,8 @@ fix_or(mrb_state *mrb, mrb_value x)
 static mrb_value
 fix_xor(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
   bit_op(x, y, or, ^);
 }
 
@@ -1096,7 +1103,7 @@ lshift(mrb_state *mrb, mrb_int val, mrb_int width)
   }
   else {
     if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
-        (val   < (MRB_INT_MIN >> width))) {
+        (val   <= (MRB_INT_MIN >> width))) {
 #ifdef MRB_WITHOUT_FLOAT
       return mrb_fixnum_value(0);
 #else
@@ -1230,15 +1237,15 @@ mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x)
       z = (mrb_int)d;
     }
     else {
-      mrb_raisef(mrb, E_ARGUMENT_ERROR, "number (%S) too big for integer", x);
+      mrb_raisef(mrb, E_RANGE_ERROR, "number (%v) too big for integer", x);
     }
   }
   return mrb_fixnum_value(z);
 }
 #endif
 
-mrb_value
-mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
+static mrb_value
+fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
 {
   mrb_int a;
 
@@ -1262,6 +1269,21 @@ mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
 #endif
 }
 
+MRB_API mrb_value
+mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y)
+{
+  if (mrb_fixnum_p(x)) {
+    return fixnum_plus(mrb, x, y);
+  }
+#ifndef MRB_WITHOUT_FLOAT
+  if (mrb_float_p(x)) {
+    return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y));
+  }
+#endif
+  mrb_raise(mrb, E_TYPE_ERROR, "no number addition");
+  return mrb_nil_value();       /* not reached */
+}
+
 /* 15.2.8.3.1  */
 /*
  * call-seq:
@@ -1274,14 +1296,13 @@ mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
 static mrb_value
 fix_plus(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other;
+  mrb_value other = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &other);
-  return mrb_fixnum_plus(mrb, self, other);
+  return fixnum_plus(mrb, self, other);
 }
 
-mrb_value
-mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
+static mrb_value
+fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
 {
   mrb_int a;
 
@@ -1304,6 +1325,21 @@ mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
 #endif
 }
 
+MRB_API mrb_value
+mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y)
+{
+  if (mrb_fixnum_p(x)) {
+    return fixnum_minus(mrb, x, y);
+  }
+#ifndef MRB_WITHOUT_FLOAT
+  if (mrb_float_p(x)) {
+    return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y));
+  }
+#endif
+  mrb_raise(mrb, E_TYPE_ERROR, "no number subtraction");
+  return mrb_nil_value();       /* not reached */
+}
+
 /* 15.2.8.3.2  */
 /* 15.2.8.3.16 */
 /*
@@ -1317,10 +1353,9 @@ mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
 static mrb_value
 fix_minus(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other;
+  mrb_value other = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &other);
-  return mrb_fixnum_minus(mrb, self, other);
+  return fixnum_minus(mrb, self, other);
 }
 
 
@@ -1330,9 +1365,10 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base)
   char buf[MRB_INT_BIT+1];
   char *b = buf + sizeof buf;
   mrb_int val = mrb_fixnum(x);
+  mrb_value str;
 
   if (base < 2 || 36 < base) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base);
   }
 
   if (val == 0) {
@@ -1350,7 +1386,9 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base)
     } while (val /= base);
   }
 
-  return mrb_str_new(mrb, b, buf + sizeof(buf) - b);
+  str = mrb_str_new(mrb, b, buf + sizeof(buf) - b);
+  RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+  return str;
 }
 
 /* 15.2.8.3.25 */
@@ -1421,41 +1459,38 @@ cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2)
 /* 15.2.9.3.6  */
 /*
  * call-seq:
- *     self.f <=> other.f    => -1, 0, +1
+ *     self.f <=> other.f    => -1, 0, +1, or nil
  *             <  => -1
  *             =  =>  0
  *             >  => +1
  *  Comparison---Returns -1, 0, or +1 depending on whether <i>fix</i> is
  *  less than, equal to, or greater than <i>numeric</i>. This is the
- *  basis for the tests in <code>Comparable</code>.
+ *  basis for the tests in <code>Comparable</code>. When the operands are
+ *  not comparable, it returns nil instead of raising an exception.
  */
 static mrb_value
-num_cmp(mrb_state *mrb, mrb_value self)
+integral_cmp(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other;
+  mrb_value other = mrb_get_arg1(mrb);
   mrb_int n;
 
-  mrb_get_args(mrb, "o", &other);
   n = cmpnum(mrb, self, other);
   if (n == -2) return mrb_nil_value();
   return mrb_fixnum_value(n);
 }
 
-static void
+static mrb_noreturn void
 cmperr(mrb_state *mrb, mrb_value v1, mrb_value v2)
 {
-  mrb_raisef(mrb, E_ARGUMENT_ERROR, "comparison of %S with %S failed",
-             mrb_obj_value(mrb_class(mrb, v1)),
-             mrb_obj_value(mrb_class(mrb, v2)));
+  mrb_raisef(mrb, E_ARGUMENT_ERROR, "comparison of %t with %t failed", v1, v2);
 }
 
 static mrb_value
-num_lt(mrb_state *mrb, mrb_value self)
+integral_lt(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other;
+  mrb_value other = mrb_get_arg1(mrb);
   mrb_int n;
 
-  mrb_get_args(mrb, "o", &other);
   n = cmpnum(mrb, self, other);
   if (n == -2) cmperr(mrb, self, other);
   if (n < 0) return mrb_true_value();
@@ -1463,12 +1498,11 @@ num_lt(mrb_state *mrb, mrb_value self)
 }
 
 static mrb_value
-num_le(mrb_state *mrb, mrb_value self)
+integral_le(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other;
+  mrb_value other = mrb_get_arg1(mrb);
   mrb_int n;
 
-  mrb_get_args(mrb, "o", &other);
   n = cmpnum(mrb, self, other);
   if (n == -2) cmperr(mrb, self, other);
   if (n <= 0) return mrb_true_value();
@@ -1476,12 +1510,11 @@ num_le(mrb_state *mrb, mrb_value self)
 }
 
 static mrb_value
-num_gt(mrb_state *mrb, mrb_value self)
+integral_gt(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other;
+  mrb_value other = mrb_get_arg1(mrb);
   mrb_int n;
 
-  mrb_get_args(mrb, "o", &other);
   n = cmpnum(mrb, self, other);
   if (n == -2) cmperr(mrb, self, other);
   if (n > 0) return mrb_true_value();
@@ -1489,29 +1522,47 @@ num_gt(mrb_state *mrb, mrb_value self)
 }
 
 static mrb_value
-num_ge(mrb_state *mrb, mrb_value self)
+integral_ge(mrb_state *mrb, mrb_value self)
 {
-  mrb_value other;
+  mrb_value other = mrb_get_arg1(mrb);
   mrb_int n;
 
-  mrb_get_args(mrb, "o", &other);
   n = cmpnum(mrb, self, other);
   if (n == -2) cmperr(mrb, self, other);
   if (n >= 0) return mrb_true_value();
   return mrb_false_value();
 }
 
+MRB_API mrb_int
+mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
+{
+  mrb_value v;
+
+  switch (mrb_type(obj1)) {
+  case MRB_TT_FIXNUM:
+  case MRB_TT_FLOAT:
+    return cmpnum(mrb, obj1, obj2);
+  case MRB_TT_STRING:
+    if (!mrb_string_p(obj2))
+      return -2;
+    return mrb_str_cmp(mrb, obj1, obj2);
+  default:
+    v = mrb_funcall(mrb, obj1, "<=>", 1, obj2);
+    if (mrb_nil_p(v) || !mrb_fixnum_p(v))
+      return -2;
+    return mrb_fixnum(v);
+  }
+}
+
 static mrb_value
 num_finite_p(mrb_state *mrb, mrb_value self)
 {
-  mrb_get_args(mrb, "");
   return mrb_true_value();
 }
 
 static mrb_value
 num_infinite_p(mrb_state *mrb, mrb_value self)
 {
-  mrb_get_args(mrb, "");
   return mrb_false_value();
 }
 
@@ -1527,9 +1578,8 @@ num_infinite_p(mrb_state *mrb, mrb_value self)
 static mrb_value
 flo_plus(mrb_state *mrb, mrb_value x)
 {
-  mrb_value y;
+  mrb_value y = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &y);
   return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y));
 }
 #endif
@@ -1544,21 +1594,21 @@ mrb_init_numeric(mrb_state *mrb)
 #endif
 
   integral = mrb_define_module(mrb, "Integral");
+  mrb_define_method(mrb, integral,"**",       integral_pow,    MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, integral,"/",        integral_div,    MRB_ARGS_REQ(1)); /* 15.2.{8,9}.3.6  */
+  mrb_define_method(mrb, integral,"quo",      integral_div,    MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
+  mrb_define_method(mrb, integral,"div",      integral_idiv,   MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, integral,"<=>",      integral_cmp,    MRB_ARGS_REQ(1)); /* 15.2.{8,9}.3.1  */
+  mrb_define_method(mrb, integral,"<",        integral_lt,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, integral,"<=",       integral_le,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, integral,">",        integral_gt,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, integral,">=",       integral_ge,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, integral,"__coerce_step_counter", integral_coerce_step_counter, MRB_ARGS_REQ(2));
 
   /* Numeric Class */
   numeric = mrb_define_class(mrb, "Numeric",  mrb->object_class);                /* 15.2.7 */
-
-  mrb_define_method(mrb, numeric, "**",       num_pow,         MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, numeric, "/",        num_div,         MRB_ARGS_REQ(1)); /* 15.2.8.3.4  */
-  mrb_define_method(mrb, numeric, "quo",      num_div,         MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
-  mrb_define_method(mrb, numeric, "<=>",      num_cmp,         MRB_ARGS_REQ(1)); /* 15.2.9.3.6  */
-  mrb_define_method(mrb, numeric, "<",        num_lt,          MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, numeric, "<=",       num_le,          MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, numeric, ">",        num_gt,          MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, numeric, ">=",       num_ge,          MRB_ARGS_REQ(1));
   mrb_define_method(mrb, numeric, "finite?",  num_finite_p,    MRB_ARGS_NONE());
   mrb_define_method(mrb, numeric, "infinite?",num_infinite_p,  MRB_ARGS_NONE());
-  mrb_define_method(mrb, numeric, "__coerce_step_counter", num_coerce_step_counter,  MRB_ARGS_REQ(2));
 
   /* Integer Class */
   integer = mrb_define_class(mrb, "Integer",  numeric);                          /* 15.2.8 */
@@ -1567,10 +1617,10 @@ mrb_init_numeric(mrb_state *mrb)
   mrb_define_method(mrb, integer, "to_i",     int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.24 */
   mrb_define_method(mrb, integer, "to_int",   int_to_i,        MRB_ARGS_NONE());
 #ifndef MRB_WITHOUT_FLOAT
-  mrb_define_method(mrb, integer, "ceil",     int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */
-  mrb_define_method(mrb, integer, "floor",    int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */
-  mrb_define_method(mrb, integer, "round",    int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.12 (x) */
-  mrb_define_method(mrb, integer, "truncate", int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */
+  mrb_define_method(mrb, integer, "ceil",     int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.8 (x) */
+  mrb_define_method(mrb, integer, "floor",    int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.10 (x) */
+  mrb_define_method(mrb, integer, "round",    int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.12 (x) */
+  mrb_define_method(mrb, integer, "truncate", int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.15 (x) */
 #endif
 
   /* Fixnum Class */
@@ -1590,8 +1640,8 @@ mrb_init_numeric(mrb_state *mrb)
 #ifndef MRB_WITHOUT_FLOAT
   mrb_define_method(mrb, fixnum,  "to_f",     fix_to_f,        MRB_ARGS_NONE()); /* 15.2.8.3.23 */
 #endif
-  mrb_define_method(mrb, fixnum,  "to_s",     fix_to_s,        MRB_ARGS_NONE()); /* 15.2.8.3.25 */
-  mrb_define_method(mrb, fixnum,  "inspect",  fix_to_s,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, fixnum,  "to_s",     fix_to_s,        MRB_ARGS_OPT(1)); /* 15.2.8.3.25 */
+  mrb_define_method(mrb, fixnum,  "inspect",  fix_to_s,        MRB_ARGS_OPT(1));
   mrb_define_method(mrb, fixnum,  "divmod",   fix_divmod,      MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */
 
 #ifndef MRB_WITHOUT_FLOAT
@@ -1608,8 +1658,8 @@ mrb_init_numeric(mrb_state *mrb)
   mrb_define_method(mrb, fl,      "&",         flo_and,        MRB_ARGS_REQ(1));
   mrb_define_method(mrb, fl,      "|",         flo_or,         MRB_ARGS_REQ(1));
   mrb_define_method(mrb, fl,      "^",         flo_xor,        MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, fl,      ">>",        flo_lshift,     MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, fl,      "<<",        flo_rshift,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      ">>",        flo_rshift,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "<<",        flo_lshift,     MRB_ARGS_REQ(1));
   mrb_define_method(mrb, fl,      "ceil",      flo_ceil,       MRB_ARGS_NONE()); /* 15.2.9.3.8  */
   mrb_define_method(mrb, fl,      "finite?",   flo_finite_p,   MRB_ARGS_NONE()); /* 15.2.9.3.9  */
   mrb_define_method(mrb, fl,      "floor",     flo_floor,      MRB_ARGS_NONE()); /* 15.2.9.3.10 */
index d45ab27..db9dfb5 100644 (file)
@@ -47,6 +47,17 @@ mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
   mrb_value result;
 
   if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE;
+#ifndef MRB_WITHOUT_FLOAT
+  /* value mixing with integer and float */
+  if (mrb_fixnum_p(obj1)) {
+    if (mrb_float_p(obj2) && (mrb_float)mrb_fixnum(obj1) == mrb_float(obj2))
+      return TRUE;
+  }
+  else if (mrb_float_p(obj1)) {
+    if (mrb_fixnum_p(obj2) && mrb_float(obj1) == (mrb_float)mrb_fixnum(obj2))
+      return TRUE;
+  }
+#endif
   result = mrb_funcall(mrb, obj1, "==", 1, obj2);
   if (mrb_test(result)) return TRUE;
   return FALSE;
@@ -83,13 +94,17 @@ mrb_true(mrb_state *mrb, mrb_value obj)
 static mrb_value
 nil_to_s(mrb_state *mrb, mrb_value obj)
 {
-  return mrb_str_new(mrb, 0, 0);
+  mrb_value str = mrb_str_new_frozen(mrb, 0, 0);
+  RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+  return str;
 }
 
 static mrb_value
 nil_inspect(mrb_state *mrb, mrb_value obj)
 {
-  return mrb_str_new_lit(mrb, "nil");
+  mrb_value str = mrb_str_new_lit_frozen(mrb, "nil");
+  RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+  return str;
 }
 
 /***********************************************************************
@@ -150,7 +165,9 @@ true_xor(mrb_state *mrb, mrb_value obj)
 static mrb_value
 true_to_s(mrb_state *mrb, mrb_value obj)
 {
-  return mrb_str_new_lit(mrb, "true");
+  mrb_value str = mrb_str_new_lit_frozen(mrb, "true");
+  RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+  return str;
 }
 
 /* 15.2.5.3.4  */
@@ -257,7 +274,9 @@ false_or(mrb_state *mrb, mrb_value obj)
 static mrb_value
 false_to_s(mrb_state *mrb, mrb_value obj)
 {
-  return mrb_str_new_lit(mrb, "false");
+  mrb_value str = mrb_str_new_lit_frozen(mrb, "false");
+  RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+  return str;
 }
 
 void
@@ -297,17 +316,6 @@ mrb_init_object(mrb_state *mrb)
 }
 
 static mrb_value
-inspect_type(mrb_state *mrb, mrb_value val)
-{
-  if (mrb_type(val) == MRB_TT_FALSE || mrb_type(val) == MRB_TT_TRUE) {
-    return mrb_inspect(mrb, val);
-  }
-  else {
-    return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, val));
-  }
-}
-
-static mrb_value
 convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, mrb_bool raise)
 {
   mrb_sym m = 0;
@@ -315,7 +323,7 @@ convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *metho
   m = mrb_intern_cstr(mrb, method);
   if (!mrb_respond_to(mrb, val, m)) {
     if (raise) {
-      mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", inspect_type(mrb, val), mrb_str_new_cstr(mrb, tname));
+      mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y into %s", val, tname);
     }
     return mrb_nil_value();
   }
@@ -330,8 +338,7 @@ mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char
   if (mrb_type(val) == type) return val;
   v = convert_type(mrb, val, tname, method, TRUE);
   if (mrb_type(v) != type) {
-    mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to %S by #%S", val,
-               mrb_str_new_cstr(mrb, tname), mrb_str_new_cstr(mrb, method));
+    mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be converted to %s by #%s", val, tname, method);
   }
   return v;
 }
@@ -370,7 +377,6 @@ static const struct types {
   {MRB_TT_STRING, "String"},
   {MRB_TT_RANGE,  "Range"},
 /*    {MRB_TT_BIGNUM,  "Bignum"}, */
-  {MRB_TT_FILE,   "File"},
   {MRB_TT_DATA,   "Data"},  /* internal use: wrapped C pointers */
 /*    {MRB_TT_VARMAP,  "Varmap"}, */ /* internal use: dynamic variables */
 /*    {MRB_TT_NODE,  "Node"}, */ /* internal use: syntax tree node */
@@ -396,7 +402,7 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
         else if (mrb_fixnum_p(x)) {
           etype = "Fixnum";
         }
-        else if (mrb_type(x) == MRB_TT_SYMBOL) {
+        else if (mrb_symbol_p(x)) {
           etype = "Symbol";
         }
         else if (mrb_immediate_p(x)) {
@@ -405,13 +411,12 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
         else {
           etype = mrb_obj_classname(mrb, x);
         }
-        mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)",
-                   mrb_str_new_cstr(mrb, etype), mrb_str_new_cstr(mrb, type->name));
+        mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)",
+                   etype, type->name);
       }
       type++;
     }
-    mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %S (%S given)",
-               mrb_fixnum_value(t), mrb_fixnum_value(mrb_type(x)));
+    mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %d (%d given)", t, mrb_type(x));
   }
 }
 
@@ -436,7 +441,7 @@ mrb_any_to_s(mrb_state *mrb, mrb_value obj)
   mrb_str_cat_cstr(mrb, str, cname);
   if (!mrb_immediate_p(obj)) {
     mrb_str_cat_lit(mrb, str, ":");
-    mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj)));
+    mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj)));
   }
   mrb_str_cat_lit(mrb, str, ">");
 
@@ -499,15 +504,12 @@ mrb_to_int(mrb_state *mrb, mrb_value val)
 {
 
   if (!mrb_fixnum_p(val)) {
-    mrb_value type;
-
 #ifndef MRB_WITHOUT_FLOAT
     if (mrb_float_p(val)) {
       return mrb_flo_to_fixnum(mrb, val);
     }
 #endif
-    type = inspect_type(mrb, val);
-    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer", type);
+    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y to Integer", val);
   }
   return val;
 }
@@ -584,11 +586,7 @@ mrb_Float(mrb_state *mrb, mrb_value val)
 MRB_API mrb_value
 mrb_to_str(mrb_state *mrb, mrb_value val)
 {
-  if (!mrb_string_p(val)) {
-    mrb_value type = inspect_type(mrb, val);
-    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to String", type);
-  }
-  return val;
+  return mrb_ensure_string_type(mrb, val);
 }
 
 /* obsolete: use mrb_ensure_string_type() instead */
@@ -602,8 +600,7 @@ MRB_API mrb_value
 mrb_ensure_string_type(mrb_state *mrb, mrb_value str)
 {
   if (!mrb_string_p(str)) {
-    mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to String",
-               inspect_type(mrb, str));
+    mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to String", str);
   }
   return str;
 }
@@ -619,8 +616,7 @@ MRB_API mrb_value
 mrb_ensure_array_type(mrb_state *mrb, mrb_value ary)
 {
   if (!mrb_array_p(ary)) {
-    mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to Array",
-               inspect_type(mrb, ary));
+    mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Array", ary);
   }
   return ary;
 }
@@ -636,8 +632,7 @@ MRB_API mrb_value
 mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash)
 {
   if (!mrb_hash_p(hash)) {
-    mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to Hash",
-               inspect_type(mrb, hash));
+    mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Hash", hash);
   }
   return hash;
 }
index b87d2cf..ab30be1 100644 (file)
@@ -4,8 +4,6 @@
 ** See Copyright Notice in mruby.h
 */
 
-#include <stddef.h>
-#include <stdint.h>
 #include <string.h>
 #include <mruby.h>
 
index 03b5ead..a75814d 100644 (file)
@@ -7,31 +7,54 @@
 #include <mruby.h>
 #include <mruby/string.h>
 #include <mruby/variable.h>
+#include <mruby/error.h>
+#include <string.h>
 
 #ifndef MRB_DISABLE_STDIO
 static void
+printcstr(const char *str, size_t len, FILE *stream)
+{
+  if (str) {
+    fwrite(str, len, 1, stream);
+    putc('\n', stream);
+  }
+}
+
+static void
 printstr(mrb_value obj, FILE *stream)
 {
   if (mrb_string_p(obj)) {
-    fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stream);
-    putc('\n', stream);
+    printcstr(RSTRING_PTR(obj), RSTRING_LEN(obj), stream);
   }
 }
 #else
+# define printcstr(str, len, stream) (void)0
 # define printstr(obj, stream) (void)0
 #endif
 
+void
+mrb_core_init_printabort(void)
+{
+  static const char *str = "Failed mruby core initialization";
+  printcstr(str, strlen(str), stdout);
+}
+
 MRB_API void
 mrb_p(mrb_state *mrb, mrb_value obj)
 {
-  printstr(mrb_inspect(mrb, obj), stdout);
+  if (mrb_type(obj) == MRB_TT_EXCEPTION && mrb_obj_ptr(obj) == mrb->nomem_err) {
+    static const char *str = "Out of memory";
+    printcstr(str, strlen(str), stdout);
+  }
+  else {
+    printstr(mrb_inspect(mrb, obj), stdout);
+  }
 }
 
 MRB_API void
 mrb_print_error(mrb_state *mrb)
 {
   mrb_print_backtrace(mrb);
-  printstr(mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0), stderr);
 }
 
 MRB_API void
index dab95e4..c00b09a 100644 (file)
@@ -8,8 +8,9 @@
 #include <mruby/class.h>
 #include <mruby/proc.h>
 #include <mruby/opcode.h>
+#include <mruby/data.h>
 
-static mrb_code call_iseq[] = {
+static const mrb_code call_iseq[] = {
   OP_CALL,
 };
 
@@ -46,7 +47,7 @@ env_new(mrb_state *mrb, mrb_int nlocals)
   int bidx;
 
   e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL);
-  MRB_ENV_SET_STACK_LEN(e, nlocals);
+  MRB_ENV_SET_LEN(e, nlocals);
   bidx = ci->argc;
   if (ci->argc < 0) bidx = 2;
   else bidx += 1;
@@ -77,6 +78,9 @@ closure_setup(mrb_state *mrb, struct RProc *p)
       e->c = tc;
       mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)tc);
     }
+    if (MRB_PROC_ENV_P(up) && MRB_PROC_ENV(up)->cxt == NULL) {
+      e->mid = MRB_PROC_ENV(up)->mid;
+    }
   }
   if (e) {
     p->e.env = e;
@@ -118,8 +122,15 @@ mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const
   p->e.env = e = env_new(mrb, argc);
   p->flags |= MRB_PROC_ENVSET;
   mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)e);
-  MRB_ENV_UNSHARE_STACK(e);
+  MRB_ENV_CLOSE(e);
+
+  /* NOTE: Prevents keeping invalid addresses when NoMemoryError is raised from `mrb_malloc()`. */
+  e->stack = NULL;
+  MRB_ENV_SET_LEN(e, 0);
+
   e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc);
+  MRB_ENV_SET_LEN(e, argc);
+
   if (argv) {
     for (i = 0; i < argc; ++i) {
       e->stack[i] = argv[i];
@@ -152,9 +163,9 @@ mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx)
   if (!e) {
     mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv.");
   }
-  if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) {
-    mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)",
-               mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e)));
+  if (idx < 0 || MRB_ENV_LEN(e) <= idx) {
+    mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %i (expected: 0 <= index < %i)",
+               idx, MRB_ENV_LEN(e));
   }
 
   return e->stack[idx];
@@ -184,11 +195,8 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class)
   mrb_value proc;
   struct RProc *p;
 
-  mrb_get_args(mrb, "&", &blk);
-  if (mrb_nil_p(blk)) {
-    /* Calling Proc.new without a block is not implemented yet */
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
-  }
+  /* Calling Proc.new without a block is not implemented yet */
+  mrb_get_args(mrb, "&!", &blk);
   p = (struct RProc *)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb_class_ptr(proc_class));
   mrb_proc_copy(p, mrb_proc_ptr(blk));
   proc = mrb_obj_value(p);
@@ -203,56 +211,20 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class)
 static mrb_value
 mrb_proc_init_copy(mrb_state *mrb, mrb_value self)
 {
-  mrb_value proc;
+  mrb_value proc = mrb_get_arg1(mrb);
 
-  mrb_get_args(mrb, "o", &proc);
-  if (mrb_type(proc) != MRB_TT_PROC) {
+  if (!mrb_proc_p(proc)) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
   }
   mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc));
   return self;
 }
 
-int
-mrb_proc_cfunc_p(struct RProc *p)
-{
-  return MRB_PROC_CFUNC_P(p);
-}
-
 /* 15.2.17.4.2 */
 static mrb_value
-mrb_proc_arity(mrb_state *mrb, mrb_value self)
+proc_arity(mrb_state *mrb, mrb_value self)
 {
-  struct RProc *p = mrb_proc_ptr(self);
-  struct mrb_irep *irep;
-  mrb_code *pc;
-  mrb_aspec aspec;
-  int ma, op, ra, pa, arity;
-
-  if (MRB_PROC_CFUNC_P(p)) {
-    /* TODO cfunc aspec not implemented yet */
-    return mrb_fixnum_value(-1);
-  }
-
-  irep = p->body.irep;
-  if (!irep) {
-    return mrb_fixnum_value(0);
-  }
-
-  pc = irep->iseq;
-  /* arity is depend on OP_ENTER */
-  if (*pc != OP_ENTER) {
-    return mrb_fixnum_value(0);
-  }
-
-  aspec = PEEK_W(pc+1);
-  ma = MRB_ASPEC_REQ(aspec);
-  op = MRB_ASPEC_OPT(aspec);
-  ra = MRB_ASPEC_REST(aspec);
-  pa = MRB_ASPEC_POST(aspec);
-  arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa;
-
-  return mrb_fixnum_value(arity);
+  return mrb_fixnum_value(mrb_proc_arity(mrb_proc_ptr(self)));
 }
 
 /* 15.3.1.2.6  */
@@ -274,7 +246,7 @@ proc_lambda(mrb_state *mrb, mrb_value self)
   if (mrb_nil_p(blk)) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
   }
-  if (mrb_type(blk) != MRB_TT_PROC) {
+  if (!mrb_proc_p(blk)) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
   }
   p = mrb_proc_ptr(blk);
@@ -287,14 +259,59 @@ proc_lambda(mrb_state *mrb, mrb_value self)
   return blk;
 }
 
+mrb_int
+mrb_proc_arity(const struct RProc *p)
+{
+  struct mrb_irep *irep;
+  const mrb_code *pc;
+  mrb_aspec aspec;
+  int ma, op, ra, pa, arity;
+
+  if (MRB_PROC_CFUNC_P(p)) {
+    /* TODO cfunc aspec not implemented yet */
+    return -1;
+  }
+
+  irep = p->body.irep;
+  if (!irep) {
+    return 0;
+  }
+
+  pc = irep->iseq;
+  /* arity is depend on OP_ENTER */
+  if (*pc != OP_ENTER) {
+    return 0;
+  }
+
+  aspec = PEEK_W(pc+1);
+  ma = MRB_ASPEC_REQ(aspec);
+  op = MRB_ASPEC_OPT(aspec);
+  ra = MRB_ASPEC_REST(aspec);
+  pa = MRB_ASPEC_POST(aspec);
+  arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa;
+
+  return arity;
+}
+
+static void
+tempirep_free(mrb_state *mrb, void *p)
+{
+  if (p) mrb_irep_free(mrb, (mrb_irep *)p);
+}
+
+static const mrb_data_type tempirep_type = { "temporary irep", tempirep_free };
+
 void
 mrb_init_proc(mrb_state *mrb)
 {
   struct RProc *p;
   mrb_method_t m;
-  mrb_irep *call_irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
+  struct RData *irep_obj = mrb_data_object_alloc(mrb, mrb->object_class, NULL, &tempirep_type);
+  mrb_irep *call_irep;
   static const mrb_irep mrb_irep_zero = { 0 };
 
+  call_irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
+  irep_obj->data = call_irep;
   *call_irep = mrb_irep_zero;
   call_irep->flags = MRB_ISEQ_NO_FREE;
   call_irep->iseq = call_iseq;
@@ -303,9 +320,10 @@ mrb_init_proc(mrb_state *mrb)
 
   mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
   mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE());
+  mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE());
 
   p = mrb_proc_new(mrb, call_irep);
+  irep_obj->data = NULL;
   MRB_METHOD_FROM_PROC(m, p);
   mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "call"), m);
   mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "[]"), m);
index 21771c8..0b4e6db 100644 (file)
@@ -17,9 +17,9 @@
 static void
 r_check(mrb_state *mrb, mrb_value a, mrb_value b)
 {
-  mrb_value ans;
   enum mrb_vtype ta;
   enum mrb_vtype tb;
+  mrb_int n;
 
   ta = mrb_type(a);
   tb = mrb_type(b);
@@ -32,9 +32,8 @@ r_check(mrb_state *mrb, mrb_value a, mrb_value b)
     return;
   }
 
-  ans =  mrb_funcall(mrb, a, "<=>", 1, b);
-  if (mrb_nil_p(ans)) {
-    /* can not be compared */
+  n = mrb_cmp(mrb, a, b);
+  if (n == -2) {                /* can not be compared */
     mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range");
   }
 }
@@ -42,37 +41,24 @@ r_check(mrb_state *mrb, mrb_value a, mrb_value b)
 static mrb_bool
 r_le(mrb_state *mrb, mrb_value a, mrb_value b)
 {
-  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
-  /* output :a < b => -1, a = b =>  0, a > b => +1 */
-
-  if (mrb_fixnum_p(r)) {
-    mrb_int c = mrb_fixnum(r);
-    if (c == 0 || c == -1) return TRUE;
-  }
+  mrb_int n = mrb_cmp(mrb, a, b);
 
+  if (n == 0 || n == -1) return TRUE;
   return FALSE;
 }
 
 static mrb_bool
 r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
 {
-  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
-  /* output :a < b => -1, a = b =>  0, a > b => +1 */
-
-  return mrb_fixnum_p(r) && mrb_fixnum(r) == 1;
+  return mrb_cmp(mrb, a, b) == 1;
 }
 
 static mrb_bool
 r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
 {
-  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
-  /* output :a < b => -1, a = b =>  0, a > b => +1 */
-
-  if (mrb_fixnum_p(r)) {
-    mrb_int c = mrb_fixnum(r);
-    if (c == 0 || c == 1) return TRUE;
-  }
+  mrb_int n = mrb_cmp(mrb, a, b);
 
+  if (n == 0 || n == 1) return TRUE;
   return FALSE;
 }
 
@@ -92,7 +78,7 @@ range_ptr_init(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, m
   if (r) {
     if (RANGE_INITIALIZED_P(r)) {
       /* Ranges are immutable, so that they should be initialized only once. */
-      mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice");
+      mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "'initialize' called twice");
     }
     else {
       range_ptr_alloc_edges(mrb, r);
@@ -196,9 +182,8 @@ range_eq(mrb_state *mrb, mrb_value range)
 {
   struct RRange *rr;
   struct RRange *ro;
-  mrb_value obj, v1, v2;
-
-  mrb_get_args(mrb, "o", &obj);
+  mrb_value obj = mrb_get_arg1(mrb);
+  mrb_bool v1, v2;
 
   if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
   if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */
@@ -207,9 +192,9 @@ range_eq(mrb_state *mrb, mrb_value range)
 
   rr = mrb_range_ptr(mrb, range);
   ro = mrb_range_ptr(mrb, obj);
-  v1 = mrb_funcall(mrb, RANGE_BEG(rr), "==", 1, RANGE_BEG(ro));
-  v2 = mrb_funcall(mrb, RANGE_END(rr), "==", 1, RANGE_END(ro));
-  if (!mrb_bool(v1) || !mrb_bool(v2) || RANGE_EXCL(rr) != RANGE_EXCL(ro)) {
+  v1 = mrb_equal(mrb, RANGE_BEG(rr), RANGE_BEG(ro));
+  v2 = mrb_equal(mrb, RANGE_END(rr), RANGE_END(ro));
+  if (!v1 || !v2 || RANGE_EXCL(rr) != RANGE_EXCL(ro)) {
     return mrb_false_value();
   }
   return mrb_true_value();
@@ -224,13 +209,11 @@ range_eq(mrb_state *mrb, mrb_value range)
 static mrb_value
 range_include(mrb_state *mrb, mrb_value range)
 {
-  mrb_value val;
+  mrb_value val = mrb_get_arg1(mrb);
   struct RRange *r = mrb_range_ptr(mrb, range);
   mrb_value beg, end;
   mrb_bool include_p;
 
-  mrb_get_args(mrb, "o", &val);
-
   beg = RANGE_BEG(r);
   end = RANGE_END(r);
   include_p = r_le(mrb, beg, val) &&                 /* beg <= val */
@@ -302,14 +285,12 @@ range_inspect(mrb_state *mrb, mrb_value range)
 static mrb_value
 range_eql(mrb_state *mrb, mrb_value range)
 {
-  mrb_value obj;
+  mrb_value obj = mrb_get_arg1(mrb);
   struct RRange *r, *o;
 
-  mrb_get_args(mrb, "o", &obj);
-
   if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
   if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) return mrb_false_value();
-  if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();
+  if (!mrb_range_p(obj)) return mrb_false_value();
 
   r = mrb_range_ptr(mrb, range);
   o = mrb_range_ptr(mrb, obj);
@@ -325,11 +306,9 @@ range_eql(mrb_state *mrb, mrb_value range)
 static mrb_value
 range_initialize_copy(mrb_state *mrb, mrb_value copy)
 {
-  mrb_value src;
+  mrb_value src = mrb_get_arg1(mrb);
   struct RRange *r;
 
-  mrb_get_args(mrb, "o", &src);
-
   if (mrb_obj_equal(mrb, copy, src)) return copy;
   if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
     mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
@@ -352,7 +331,7 @@ mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, con
     if (mrb_fixnum_p(argv[i])) {
       mrb_ary_push(mrb, result, func(mrb, obj, mrb_fixnum(argv[i])));
     }
-    else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == 1) {
+    else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == MRB_RANGE_OK) {
       mrb_int const end = olen < beg + len ? olen : beg + len;
       for (j = beg; j < end; ++j) {
         mrb_ary_push(mrb, result, func(mrb, obj, j));
@@ -363,7 +342,7 @@ mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, con
       }
     }
     else {
-      mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %S", argv[i]);
+      mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %v", argv[i]);
     }
   }
 
@@ -398,13 +377,13 @@ mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl)
   return mrb_range_value(r);
 }
 
-MRB_API mrb_int
+MRB_API enum mrb_range_beg_len
 mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
 {
   mrb_int beg, end;
   struct RRange *r;
 
-  if (mrb_type(range) != MRB_TT_RANGE) return 0;
+  if (!mrb_range_p(range)) return MRB_RANGE_TYPE_MISMATCH;
   r = mrb_range_ptr(mrb, range);
 
   beg = mrb_int(mrb, RANGE_BEG(r));
@@ -412,11 +391,11 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp,
 
   if (beg < 0) {
     beg += len;
-    if (beg < 0) return 2;
+    if (beg < 0) return MRB_RANGE_OUT;
   }
 
   if (trunc) {
-    if (beg > len) return 2;
+    if (beg > len) return MRB_RANGE_OUT;
     if (end > len) end = len;
   }
 
@@ -427,7 +406,7 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp,
 
   *begp = beg;
   *lenp = len;
-  return 1;
+  return MRB_RANGE_OK;
 }
 
 void
index c3ce1dc..533bdaa 100644 (file)
@@ -19,11 +19,25 @@ void mrb_init_mrbgems(mrb_state*);
 void mrb_gc_init(mrb_state*, mrb_gc *gc);
 void mrb_gc_destroy(mrb_state*, mrb_gc *gc);
 
+int mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state *, void *), void *opaque);
+
+static void
+init_gc_and_core(mrb_state *mrb, void *opaque)
+{
+  static const struct mrb_context mrb_context_zero = { 0 };
+
+  mrb_gc_init(mrb, &mrb->gc);
+  mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
+  *mrb->c = mrb_context_zero;
+  mrb->root_c = mrb->c;
+
+  mrb_init_core(mrb);
+}
+
 MRB_API mrb_state*
 mrb_open_core(mrb_allocf f, void *ud)
 {
   static const mrb_state mrb_state_zero = { 0 };
-  static const struct mrb_context mrb_context_zero = { 0 };
   mrb_state *mrb;
 
   if (f == NULL) f = mrb_default_allocf;
@@ -35,16 +49,10 @@ mrb_open_core(mrb_allocf f, void *ud)
   mrb->allocf = f;
   mrb->atexit_stack_len = 0;
 
-  mrb_gc_init(mrb, &mrb->gc);
-  mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
-  *mrb->c = mrb_context_zero;
-  mrb->root_c = mrb->c;
-
-  mrb_init_core(mrb);
-
-#if !defined(MRB_DISABLE_STDIO) && defined(_MSC_VER) && _MSC_VER < 1900
-  _set_output_format(_TWO_DIGIT_EXPONENT);
-#endif
+  if (mrb_core_init_protect(mrb, init_gc_and_core, NULL)) {
+    mrb_close(mrb);
+    return NULL;
+  }
 
   return mrb;
 }
@@ -61,38 +69,6 @@ mrb_default_allocf(mrb_state *mrb, void *p, size_t size, void *ud)
   }
 }
 
-struct alloca_header {
-  struct alloca_header *next;
-  char buf[1];
-};
-
-MRB_API void*
-mrb_alloca(mrb_state *mrb, size_t size)
-{
-  struct alloca_header *p;
-
-  p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
-  p->next = mrb->mems;
-  mrb->mems = p;
-  return (void*)p->buf;
-}
-
-static void
-mrb_alloca_free(mrb_state *mrb)
-{
-  struct alloca_header *p;
-  struct alloca_header *tmp;
-
-  if (mrb == NULL) return;
-  p = mrb->mems;
-
-  while (p) {
-    tmp = p;
-    p = p->next;
-    mrb_free(mrb, tmp);
-  }
-}
-
 MRB_API mrb_state*
 mrb_open(void)
 {
@@ -101,6 +77,12 @@ mrb_open(void)
   return mrb;
 }
 
+static void
+init_mrbgems(mrb_state *mrb, void *opaque)
+{
+  mrb_init_mrbgems(mrb);
+}
+
 MRB_API mrb_state*
 mrb_open_allocf(mrb_allocf f, void *ud)
 {
@@ -111,7 +93,10 @@ mrb_open_allocf(mrb_allocf f, void *ud)
   }
 
 #ifndef DISABLE_GEMS
-  mrb_init_mrbgems(mrb);
+  if (mrb_core_init_protect(mrb, init_mrbgems, NULL)) {
+    mrb_close(mrb);
+    return NULL;
+  }
   mrb_gc_arena_restore(mrb, 0);
 #endif
   return mrb;
@@ -153,23 +138,25 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
   int i;
 
   if (!(irep->flags & MRB_ISEQ_NO_FREE))
-    mrb_free(mrb, irep->iseq);
+    mrb_free(mrb, (void*)irep->iseq);
   if (irep->pool) for (i=0; i<irep->plen; i++) {
-    if (mrb_type(irep->pool[i]) == MRB_TT_STRING) {
+    if (mrb_string_p(irep->pool[i])) {
       mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
       mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
     }
 #if defined(MRB_WORD_BOXING) && !defined(MRB_WITHOUT_FLOAT)
-    else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) {
+    else if (mrb_float_p(irep->pool[i])) {
       mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
     }
 #endif
   }
   mrb_free(mrb, irep->pool);
   mrb_free(mrb, irep->syms);
-  for (i=0; i<irep->rlen; i++) {
-    if (irep->reps[i])
-      mrb_irep_decref(mrb, irep->reps[i]);
+  if (irep->reps) {
+    for (i=0; i<irep->rlen; i++) {
+      if (irep->reps[i])
+        mrb_irep_decref(mrb, irep->reps[i]);
+    }
   }
   mrb_free(mrb, irep->reps);
   mrb_free(mrb, irep->lv);
@@ -177,58 +164,6 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
   mrb_free(mrb, irep);
 }
 
-mrb_value
-mrb_str_pool(mrb_state *mrb, mrb_value str)
-{
-  struct RString *s = mrb_str_ptr(str);
-  struct RString *ns;
-  char *ptr;
-  mrb_int len;
-
-  ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
-  ns->tt = MRB_TT_STRING;
-  ns->c = mrb->string_class;
-
-  if (RSTR_NOFREE_P(s)) {
-    ns->flags = MRB_STR_NOFREE;
-    ns->as.heap.ptr = s->as.heap.ptr;
-    ns->as.heap.len = s->as.heap.len;
-    ns->as.heap.aux.capa = 0;
-  }
-  else {
-    ns->flags = 0;
-    if (RSTR_EMBED_P(s)) {
-      ptr = s->as.ary;
-      len = RSTR_EMBED_LEN(s);
-    }
-    else {
-      ptr = s->as.heap.ptr;
-      len = s->as.heap.len;
-    }
-
-    if (len < RSTRING_EMBED_LEN_MAX) {
-      RSTR_SET_EMBED_FLAG(ns);
-      RSTR_SET_EMBED_LEN(ns, len);
-      if (ptr) {
-        memcpy(ns->as.ary, ptr, len);
-      }
-      ns->as.ary[len] = '\0';
-    }
-    else {
-      ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
-      ns->as.heap.len = len;
-      ns->as.heap.aux.capa = len;
-      if (ptr) {
-        memcpy(ns->as.heap.ptr, ptr, len);
-      }
-      ns->as.heap.ptr[len] = '\0';
-    }
-  }
-  RSTR_SET_POOL_FLAG(ns);
-  MRB_SET_FROZEN_FLAG(ns);
-  return mrb_obj_value(ns);
-}
-
 void mrb_free_backtrace(mrb_state *mrb);
 
 MRB_API void
@@ -257,11 +192,10 @@ mrb_close(mrb_state *mrb)
   }
 
   /* free */
-  mrb_gc_free_gv(mrb);
+  mrb_gc_destroy(mrb, &mrb->gc);
   mrb_free_context(mrb, mrb->root_c);
+  mrb_gc_free_gv(mrb);
   mrb_free_symtbl(mrb);
-  mrb_alloca_free(mrb);
-  mrb_gc_destroy(mrb, &mrb->gc);
   mrb_free(mrb, mrb);
 }
 
index 63c592d..f1ffbe4 100644 (file)
@@ -10,6 +10,7 @@
 
 #ifndef MRB_WITHOUT_FLOAT
 #include <float.h>
+#include <math.h>
 #endif
 #include <limits.h>
 #include <stddef.h>
 #include <mruby/range.h>
 #include <mruby/string.h>
 #include <mruby/numeric.h>
-#include <mruby/re.h>
 
 typedef struct mrb_shared_string {
-  mrb_bool nofree : 1;
   int refcnt;
+  mrb_ssize capa;
   char *ptr;
-  mrb_int len;
 } mrb_shared_string;
 
 const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
@@ -35,55 +34,114 @@ const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
 #define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class))
 
 static struct RString*
-str_new_static(mrb_state *mrb, const char *p, size_t len)
+str_init_normal_capa(mrb_state *mrb, struct RString *s,
+                     const char *p, size_t len, size_t capa)
+{
+  char *dst = (char *)mrb_malloc(mrb, capa + 1);
+  if (p) memcpy(dst, p, len);
+  dst[len] = '\0';
+  s->as.heap.ptr = dst;
+  s->as.heap.len = (mrb_ssize)len;
+  s->as.heap.aux.capa = (mrb_ssize)capa;
+  RSTR_UNSET_TYPE_FLAG(s);
+  return s;
+}
+
+static struct RString*
+str_init_normal(mrb_state *mrb, struct RString *s, const char *p, size_t len)
 {
-  struct RString *s;
+  return str_init_normal_capa(mrb, s, p, len, len);
+}
 
-  if (len >= MRB_INT_MAX) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
-  }
-  s = mrb_obj_alloc_string(mrb);
-  s->as.heap.len = (mrb_int)len;
-  s->as.heap.aux.capa = 0;             /* nofree */
+static struct RString*
+str_init_embed(struct RString *s, const char *p, size_t len)
+{
+  if (p) memcpy(RSTR_EMBED_PTR(s), p, len);
+  RSTR_EMBED_PTR(s)[len] = '\0';
+  RSTR_SET_TYPE_FLAG(s, EMBED);
+  RSTR_SET_EMBED_LEN(s, len);
+  return s;
+}
+
+static struct RString*
+str_init_nofree(struct RString *s, const char *p, size_t len)
+{
   s->as.heap.ptr = (char *)p;
-  s->flags = MRB_STR_NOFREE;
+  s->as.heap.len = (mrb_ssize)len;
+  s->as.heap.aux.capa = 0;             /* nofree */
+  RSTR_SET_TYPE_FLAG(s, NOFREE);
+  return s;
+}
 
+static struct RString*
+str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, mrb_shared_string *shared)
+{
+  if (shared) {
+    shared->refcnt++;
+  }
+  else {
+    shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string));
+    shared->refcnt = 1;
+    shared->ptr = orig->as.heap.ptr;
+    shared->capa = orig->as.heap.aux.capa;
+  }
+  s->as.heap.ptr = orig->as.heap.ptr;
+  s->as.heap.len = orig->as.heap.len;
+  s->as.heap.aux.shared = shared;
+  RSTR_SET_TYPE_FLAG(s, SHARED);
   return s;
 }
 
 static struct RString*
-str_new(mrb_state *mrb, const char *p, size_t len)
+str_init_fshared(const struct RString *orig, struct RString *s, struct RString *fshared)
 {
-  struct RString *s;
+  s->as.heap.ptr = orig->as.heap.ptr;
+  s->as.heap.len = orig->as.heap.len;
+  s->as.heap.aux.fshared = fshared;
+  RSTR_SET_TYPE_FLAG(s, FSHARED);
+  return s;
+}
 
-  if (p && mrb_ro_data_p(p)) {
-    return str_new_static(mrb, p, len);
-  }
-  s = mrb_obj_alloc_string(mrb);
-  if (len <= RSTRING_EMBED_LEN_MAX) {
-    RSTR_SET_EMBED_FLAG(s);
-    RSTR_SET_EMBED_LEN(s, len);
-    if (p) {
-      memcpy(s->as.ary, p, len);
-    }
+static struct RString*
+str_init_modifiable(mrb_state *mrb, struct RString *s, const char *p, size_t len)
+{
+  if (RSTR_EMBEDDABLE_P(len)) {
+    return str_init_embed(s, p, len);
   }
   else {
-    if (len >= MRB_INT_MAX) {
-      mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
-    }
-    s->as.heap.ptr = (char *)mrb_malloc(mrb, len+1);
-    s->as.heap.len = (mrb_int)len;
-    s->as.heap.aux.capa = (mrb_int)len;
-    if (p) {
-      memcpy(s->as.heap.ptr, p, len);
-    }
+    return str_init_normal(mrb, s, p, len);
   }
-  RSTR_PTR(s)[len] = '\0';
-  return s;
+}
+
+static struct RString*
+str_new_static(mrb_state *mrb, const char *p, size_t len)
+{
+  if (RSTR_EMBEDDABLE_P(len)) {
+    return str_init_embed(mrb_obj_alloc_string(mrb), p, len);
+  }
+  if (len >= MRB_SSIZE_MAX) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
+  }
+  return str_init_nofree(mrb_obj_alloc_string(mrb), p, len);
+}
+
+static struct RString*
+str_new(mrb_state *mrb, const char *p, size_t len)
+{
+  if (RSTR_EMBEDDABLE_P(len)) {
+    return str_init_embed(mrb_obj_alloc_string(mrb), p, len);
+  }
+  if (len >= MRB_SSIZE_MAX) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
+  }
+  if (p && mrb_ro_data_p(p)) {
+    return str_init_nofree(mrb_obj_alloc_string(mrb), p, len);
+  }
+  return str_init_normal(mrb, mrb_obj_alloc_string(mrb), p, len);
 }
 
 static inline void
-str_with_class(mrb_state *mrb, struct RString *s, mrb_value obj)
+str_with_class(struct RString *s, mrb_value obj)
 {
   s->c = mrb_str_ptr(obj)->c;
 }
@@ -93,7 +151,7 @@ mrb_str_new_empty(mrb_state *mrb, mrb_value str)
 {
   struct RString *s = str_new(mrb, 0, 0);
 
-  str_with_class(mrb, s, str);
+  str_with_class(s, str);
   return mrb_obj_value(s);
 }
 
@@ -102,15 +160,17 @@ mrb_str_new_capa(mrb_state *mrb, size_t capa)
 {
   struct RString *s;
 
-  s = mrb_obj_alloc_string(mrb);
-
-  if (capa >= MRB_INT_MAX) {
+  if (RSTR_EMBEDDABLE_P(capa)) {
+    s = str_init_embed(mrb_obj_alloc_string(mrb), NULL, 0);
+  }
+  else if (capa >= MRB_SSIZE_MAX) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big");
+    /* not reached */
+    s = NULL;
+  }
+  else {
+    s = str_init_normal_capa(mrb, mrb_obj_alloc_string(mrb), NULL, 0, capa);
   }
-  s->as.heap.len = 0;
-  s->as.heap.aux.capa = (mrb_int)capa;
-  s->as.heap.ptr = (char *)mrb_malloc(mrb, capa+1);
-  RSTR_PTR(s)[0] = '\0';
 
   return mrb_obj_value(s);
 }
@@ -131,23 +191,17 @@ mrb_str_buf_new(mrb_state *mrb, size_t capa)
 static void
 resize_capa(mrb_state *mrb, struct RString *s, size_t capacity)
 {
-#if SIZE_MAX > MRB_INT_MAX
-    mrb_assert(capacity < MRB_INT_MAX);
+#if SIZE_MAX > MRB_SSIZE_MAX
+    mrb_assert(capacity < MRB_SSIZE_MAX);
 #endif
   if (RSTR_EMBED_P(s)) {
-    if (RSTRING_EMBED_LEN_MAX < capacity) {
-      char *const tmp = (char *)mrb_malloc(mrb, capacity+1);
-      const mrb_int len = RSTR_EMBED_LEN(s);
-      memcpy(tmp, s->as.ary, len);
-      RSTR_UNSET_EMBED_FLAG(s);
-      s->as.heap.ptr = tmp;
-      s->as.heap.len = len;
-      s->as.heap.aux.capa = (mrb_int)capacity;
+    if (!RSTR_EMBEDDABLE_P(capacity)) {
+      str_init_normal_capa(mrb, s, RSTR_EMBED_PTR(s), RSTR_EMBED_LEN(s), capacity);
     }
   }
   else {
     s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1);
-    s->as.heap.aux.capa = (mrb_int)capacity;
+    s->as.heap.aux.capa = (mrb_ssize)capacity;
   }
 }
 
@@ -187,13 +241,42 @@ str_decref(mrb_state *mrb, mrb_shared_string *shared)
 {
   shared->refcnt--;
   if (shared->refcnt == 0) {
-    if (!shared->nofree) {
-      mrb_free(mrb, shared->ptr);
-    }
+    mrb_free(mrb, shared->ptr);
     mrb_free(mrb, shared);
   }
 }
 
+static void
+str_modify_keep_ascii(mrb_state *mrb, struct RString *s)
+{
+  if (RSTR_SHARED_P(s)) {
+    mrb_shared_string *shared = s->as.heap.aux.shared;
+
+    if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) {
+      s->as.heap.aux.capa = shared->capa;
+      s->as.heap.ptr[s->as.heap.len] = '\0';
+      RSTR_UNSET_SHARED_FLAG(s);
+      mrb_free(mrb, shared);
+    }
+    else {
+      str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len);
+      str_decref(mrb, shared);
+    }
+  }
+  else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) {
+    str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len);
+  }
+}
+
+static void
+check_null_byte(mrb_state *mrb, mrb_value str)
+{
+  mrb_to_str(mrb, str);
+  if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
+  }
+}
+
 void
 mrb_gc_free_str(mrb_state *mrb, struct RString *str)
 {
@@ -218,14 +301,16 @@ static const char utf8len_codepage[256] =
   3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,
 };
 
-static mrb_int
-utf8len(const char* p, const char* e)
+mrb_int
+mrb_utf8len(const char* p, const char* e)
 {
   mrb_int len;
   mrb_int i;
 
+  if ((unsigned char)*p < 0x80) return 1;
   len = utf8len_codepage[(unsigned char)*p];
-  if (p + len > e) return 1;
+  if (len == 1) return 1;
+  if (len > e - p) return 1;
   for (i = 1; i < len; ++i)
     if ((p[i] & 0xc0) != 0x80)
       return 1;
@@ -233,14 +318,14 @@ utf8len(const char* p, const char* e)
 }
 
 mrb_int
-mrb_utf8_len(const char *str, mrb_int byte_len)
+mrb_utf8_strlen(const char *str, mrb_int byte_len)
 {
   mrb_int total = 0;
   const char *p = str;
   const char *e = p + byte_len;
 
   while (p < e) {
-    p += utf8len(p, e);
+    p += mrb_utf8len(p, e);
     total++;
   }
   return total;
@@ -249,14 +334,15 @@ mrb_utf8_len(const char *str, mrb_int byte_len)
 static mrb_int
 utf8_strlen(mrb_value str)
 {
-  mrb_int byte_len = RSTRING_LEN(str);
+  struct RString *s = mrb_str_ptr(str);
+  mrb_int byte_len = RSTR_LEN(s);
 
-  if (RSTRING(str)->flags & MRB_STR_NO_UTF) {
+  if (RSTR_ASCII_P(s)) {
     return byte_len;
   }
   else {
-    mrb_int utf8_len = mrb_utf8_len(RSTRING_PTR(str), byte_len);
-    if (byte_len == utf8_len) RSTRING(str)->flags |= MRB_STR_NO_UTF;
+    mrb_int utf8_len = mrb_utf8_strlen(RSTR_PTR(s), byte_len);
+    if (byte_len == utf8_len) RSTR_SET_ASCII_FLAG(s);
     return utf8_len;
   }
 }
@@ -267,60 +353,196 @@ utf8_strlen(mrb_value str)
 static mrb_int
 chars2bytes(mrb_value s, mrb_int off, mrb_int idx)
 {
-  mrb_int i, b, n;
-  const char *p = RSTRING_PTR(s) + off;
-  const char *e = RSTRING_END(s);
+  if (RSTR_ASCII_P(mrb_str_ptr(s))) {
+    return idx;
+  }
+  else {
+    mrb_int i, b, n;
+    const char *p = RSTRING_PTR(s) + off;
+    const char *e = RSTRING_END(s);
 
-  for (b=i=0; p<e && i<idx; i++) {
-    n = utf8len(p, e);
-    b += n;
-    p += n;
+    for (b=i=0; p<e && i<idx; i++) {
+      n = mrb_utf8len(p, e);
+      b += n;
+      p += n;
+    }
+    return b;
   }
-  return b;
 }
 
 /* map byte offset to character index */
 static mrb_int
-bytes2chars(char *p, mrb_int bi)
+bytes2chars(char *p, mrb_int len, mrb_int bi)
 {
-  mrb_int i, b, n;
+  const char *e = p + (size_t)len;
+  const char *pivot = p + bi;
+  mrb_int i;
 
-  for (b=i=0; b<bi; i++) {
-    n = utf8len_codepage[(unsigned char)*p];
-    b += n;
-    p += n;
+  for (i = 0; p < pivot; i ++) {
+    p += mrb_utf8len(p, e);
   }
-  if (b != bi) return -1;
+  if (p != pivot) return -1;
   return i;
 }
 
+static const char *
+char_adjust(const char *beg, const char *end, const char *ptr)
+{
+  if ((ptr > beg || ptr < end) && (*ptr & 0xc0) == 0x80) {
+    const int utf8_adjust_max = 3;
+    const char *p;
+
+    if (ptr - beg > utf8_adjust_max) {
+      beg = ptr - utf8_adjust_max;
+    }
+
+    p = ptr;
+    while (p > beg) {
+      p --;
+      if ((*p & 0xc0) != 0x80) {
+        int clen = mrb_utf8len(p, end);
+        if (clen > ptr - p) return p;
+        break;
+      }
+    }
+  }
+
+  return ptr;
+}
+
+static const char *
+char_backtrack(const char *ptr, const char *end)
+{
+  if (ptr < end) {
+    const int utf8_bytelen_max = 4;
+    const char *p;
+
+    if (end - ptr > utf8_bytelen_max) {
+      ptr = end - utf8_bytelen_max;
+    }
+
+    p = end;
+    while (p > ptr) {
+      p --;
+      if ((*p & 0xc0) != 0x80) {
+        int clen = utf8len_codepage[(unsigned char)*p];
+        if (clen == end - p) { return p; }
+        break;
+      }
+    }
+  }
+
+  return end - 1;
+}
+
+static mrb_int
+str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, const char *s, const mrb_int slen, mrb_int off)
+{
+  /* Based on Quick Search algorithm (Boyer-Moore-Horspool algorithm) */
+
+  ptrdiff_t qstable[1 << CHAR_BIT];
+
+  /* Preprocessing */
+  {
+    mrb_int i;
+
+    for (i = 0; i < 1 << CHAR_BIT; i ++) {
+      qstable[i] = slen;
+    }
+    for (i = 0; i < slen; i ++) {
+      qstable[(unsigned char)s[i]] = slen - (i + 1);
+    }
+  }
+
+  /* Searching */
+  while (p < pend && pend - p >= slen) {
+    const char *pivot;
+
+    if (memcmp(p, s, slen) == 0) {
+      return off;
+    }
+
+    pivot = p + qstable[(unsigned char)p[slen - 1]];
+    if (pivot >= pend || pivot < p /* overflowed */) { return -1; }
+
+    do {
+      p += mrb_utf8len(p, pend);
+      off ++;
+    } while (p < pivot);
+  }
+
+  return -1;
+}
+
+static mrb_int
+str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
+{
+  const char *p = RSTRING_PTR(str);
+  const char *pend = p + RSTRING_LEN(str);
+  const char *s = RSTRING_PTR(sub);
+  const mrb_int slen = RSTRING_LEN(sub);
+  mrb_int off = pos;
+
+  for (; pos > 0; pos --) {
+    if (pend - p < 1) { return -1; }
+    p += mrb_utf8len(p, pend);
+  }
+
+  if (slen < 1) { return off; }
+
+  return str_index_str_by_char_search(mrb, p, pend, s, slen, off);
+}
+
 #define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value();
 #else
 #define RSTRING_CHAR_LEN(s) RSTRING_LEN(s)
 #define chars2bytes(p, off, ci) (ci)
-#define bytes2chars(p, bi) (bi)
+#define bytes2chars(p, end, bi) (bi)
+#define char_adjust(beg, end, ptr) (ptr)
+#define char_backtrack(ptr, end) ((end) - 1)
 #define BYTES_ALIGN_CHECK(pos)
+#define str_index_str_by_char(mrb, str, sub, pos) str_index_str(mrb, str, sub, pos)
+#endif
+
+#ifndef MRB_QS_SHORT_STRING_LENGTH
+#define MRB_QS_SHORT_STRING_LENGTH 2048
 #endif
 
 static inline mrb_int
 mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n)
 {
-  const unsigned char *x = xs, *xe = xs + m;
-  const unsigned char *y = ys;
-  int i;
-  ptrdiff_t qstable[256];
+  if (n + m < MRB_QS_SHORT_STRING_LENGTH) {
+    const unsigned char *y = ys;
+    const unsigned char *ye = ys+n-m+1;
 
-  /* Preprocessing */
-  for (i = 0; i < 256; ++i)
-    qstable[i] = m + 1;
-  for (; x < xe; ++x)
-    qstable[*x] = xe - x;
-  /* Searching */
-  for (; y + m <= ys + n; y += *(qstable + y[m])) {
-    if (*xs == *y && memcmp(xs, y, m) == 0)
-      return (mrb_int)(y - ys);
+    for (;;) {
+      y = (const unsigned char*)memchr(y, xs[0], (size_t)(ye-y));
+      if (y == NULL) return -1;
+      if (memcmp(xs, y, m) == 0) {
+        return (mrb_int)(y - ys);
+      }
+      y++;
+    }
+    return -1;
+  }
+  else {
+    const unsigned char *x = xs, *xe = xs + m;
+    const unsigned char *y = ys;
+    int i;
+    ptrdiff_t qstable[256];
+
+    /* Preprocessing */
+    for (i = 0; i < 256; ++i)
+      qstable[i] = m + 1;
+    for (; x < xe; ++x)
+      qstable[*x] = xe - x;
+    /* Searching */
+    for (; y + m <= ys + n; y += *(qstable + y[m])) {
+      if (*xs == *y && memcmp(xs, y, m) == 0)
+        return (mrb_int)(y - ys);
+    }
+    return -1;
   }
-  return -1;
 }
 
 static mrb_int
@@ -347,113 +569,113 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n)
 }
 
 static void
-str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s)
+str_share(mrb_state *mrb, struct RString *orig, struct RString *s)
 {
-  mrb_shared_string *shared;
-  mrb_int len = RSTR_LEN(orig);
+  size_t len = (size_t)orig->as.heap.len;
 
   mrb_assert(!RSTR_EMBED_P(orig));
-  if (RSTR_SHARED_P(orig)) {
-    shared = orig->as.heap.aux.shared;
-    shared->refcnt++;
-    s->as.heap.ptr = orig->as.heap.ptr;
-    s->as.heap.len = len;
-    s->as.heap.aux.shared = shared;
-    RSTR_SET_SHARED_FLAG(s);
-    RSTR_UNSET_EMBED_FLAG(s);
+  if (RSTR_NOFREE_P(orig)) {
+    str_init_nofree(s, orig->as.heap.ptr, len);
+  }
+  else if (RSTR_SHARED_P(orig)) {
+    str_init_shared(mrb, orig, s, orig->as.heap.aux.shared);
   }
   else if (RSTR_FSHARED_P(orig)) {
-    struct RString *fs;
-
-    fs = orig->as.heap.aux.fshared;
-    s->as.heap.ptr = orig->as.heap.ptr;
-    s->as.heap.len = len;
-    s->as.heap.aux.fshared = fs;
-    RSTR_SET_FSHARED_FLAG(s);
-    RSTR_UNSET_EMBED_FLAG(s);
-  }
-  else if (MRB_FROZEN_P(orig) && !RSTR_POOL_P(orig)) {
-    s->as.heap.ptr = orig->as.heap.ptr;
-    s->as.heap.len = len;
-    s->as.heap.aux.fshared = orig;
-    RSTR_SET_FSHARED_FLAG(s);
-    RSTR_UNSET_EMBED_FLAG(s);
+    str_init_fshared(orig, s, orig->as.heap.aux.fshared);
+  }
+  else if (mrb_frozen_p(orig) && !RSTR_POOL_P(orig)) {
+    str_init_fshared(orig, s, orig);
   }
   else {
-    shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string));
-    shared->refcnt = 2;
-    shared->nofree = !!RSTR_NOFREE_P(orig);
-    if (!shared->nofree && orig->as.heap.aux.capa > orig->as.heap.len) {
-      shared->ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1);
-      orig->as.heap.ptr = shared->ptr;
-    }
-    else {
-      shared->ptr = orig->as.heap.ptr;
+    if (orig->as.heap.aux.capa > orig->as.heap.len) {
+      orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1);
+      orig->as.heap.aux.capa = (mrb_ssize)len;
     }
-    orig->as.heap.aux.shared = shared;
-    RSTR_SET_SHARED_FLAG(orig);
-    shared->len = len;
-    s->as.heap.aux.shared = shared;
-    s->as.heap.ptr = shared->ptr;
-    s->as.heap.len = len;
-    RSTR_SET_SHARED_FLAG(s);
-    RSTR_UNSET_EMBED_FLAG(s);
+    str_init_shared(mrb, orig, s, NULL);
+    str_init_shared(mrb, orig, orig, s->as.heap.aux.shared);
   }
 }
 
-static mrb_value
-byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
+mrb_value
+mrb_str_pool(mrb_state *mrb, const char *p, mrb_int len, mrb_bool nofree)
+{
+  struct RString *s = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
+
+  s->tt = MRB_TT_STRING;
+  s->c = mrb->string_class;
+  s->flags = 0;
+
+  if (RSTR_EMBEDDABLE_P(len)) {
+    str_init_embed(s, p, len);
+  }
+  else if (nofree) {
+    str_init_nofree(s, p, len);
+  }
+  else {
+    str_init_normal(mrb, s, p, len);
+  }
+  RSTR_SET_POOL_FLAG(s);
+  MRB_SET_FROZEN_FLAG(s);
+  return mrb_obj_value(s);
+}
+
+mrb_value
+mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
 {
   struct RString *orig, *s;
 
   orig = mrb_str_ptr(str);
-  if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0 || len <= RSTRING_EMBED_LEN_MAX) {
-    s = str_new(mrb, RSTR_PTR(orig)+beg, len);
+  s = mrb_obj_alloc_string(mrb);
+  if (RSTR_EMBEDDABLE_P(len)) {
+    str_init_embed(s, RSTR_PTR(orig)+beg, len);
   }
   else {
-    s = mrb_obj_alloc_string(mrb);
-    str_make_shared(mrb, orig, s);
-    s->as.heap.ptr += beg;
-    s->as.heap.len = len;
+    str_share(mrb, orig, s);
+    s->as.heap.ptr += (mrb_ssize)beg;
+    s->as.heap.len = (mrb_ssize)len;
   }
+  RSTR_COPY_ASCII_FLAG(s, orig);
   return mrb_obj_value(s);
 }
+
+static void
+str_range_to_bytes(mrb_value str, mrb_int *pos, mrb_int *len)
+{
+  *pos = chars2bytes(str, 0, *pos);
+  *len = chars2bytes(str, *pos, *len);
+}
 #ifdef MRB_UTF8_STRING
 static inline mrb_value
 str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
 {
-  beg = chars2bytes(str, 0, beg);
-  len = chars2bytes(str, beg, len);
-
-  return byte_subseq(mrb, str, beg, len);
+  str_range_to_bytes(str, &beg, &len);
+  return mrb_str_byte_subseq(mrb, str, beg, len);
 }
 #else
-#define str_subseq(mrb, str, beg, len) byte_subseq(mrb, str, beg, len)
+#define str_subseq(mrb, str, beg, len) mrb_str_byte_subseq(mrb, str, beg, len)
 #endif
 
-static mrb_value
-str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
+mrb_bool
+mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp)
 {
-  mrb_int clen = RSTRING_CHAR_LEN(str);
-
-  if (len < 0) return mrb_nil_value();
-  if (clen == 0) {
-    len = 0;
-  }
-  else if (beg < 0) {
-    beg = clen + beg;
+  if (str_len < *begp || *lenp < 0) return FALSE;
+  if (*begp < 0) {
+    *begp += str_len;
+    if (*begp < 0) return FALSE;
   }
-  if (beg > clen) return mrb_nil_value();
-  if (beg < 0) {
-    beg += clen;
-    if (beg < 0) return mrb_nil_value();
+  if (*lenp > str_len - *begp)
+    *lenp = str_len - *begp;
+  if (*lenp <= 0) {
+    *lenp = 0;
   }
-  if (len > clen - beg)
-    len = clen - beg;
-  if (len <= 0) {
-    len = 0;
-  }
-  return str_subseq(mrb, str, beg, len);
+  return TRUE;
+}
+
+static mrb_value
+str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
+{
+  return mrb_str_beg_len(RSTRING_CHAR_LEN(str), &beg, &len) ?
+    str_subseq(mrb, str, beg, len) : mrb_nil_value();
 }
 
 MRB_API mrb_int
@@ -493,44 +715,28 @@ str_index_str(mrb_state *mrb, mrb_value str, mrb_value str2, mrb_int offset)
   return mrb_str_index(mrb, str, ptr, len, offset);
 }
 
-static void
-check_frozen(mrb_state *mrb, struct RString *s)
-{
-  if (MRB_FROZEN_P(s)) {
-    mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen string");
-  }
-}
-
 static mrb_value
 str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
 {
-  mrb_int len;
+  size_t len;
 
-  check_frozen(mrb, s1);
+  mrb_check_frozen(mrb, s1);
   if (s1 == s2) return mrb_obj_value(s1);
-  s1->flags &= ~MRB_STR_NO_UTF;
-  s1->flags |= s2->flags&MRB_STR_NO_UTF;
-  len = RSTR_LEN(s2);
+  RSTR_COPY_ASCII_FLAG(s1, s2);
   if (RSTR_SHARED_P(s1)) {
     str_decref(mrb, s1->as.heap.aux.shared);
-    RSTR_UNSET_SHARED_FLAG(s1);
   }
   else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1) && !RSTR_FSHARED_P(s1)
            && s1->as.heap.ptr) {
     mrb_free(mrb, s1->as.heap.ptr);
   }
 
-  RSTR_UNSET_FSHARED_FLAG(s1);
-  RSTR_UNSET_NOFREE_FLAG(s1);
-  if (len <= RSTRING_EMBED_LEN_MAX) {
-    RSTR_UNSET_SHARED_FLAG(s1);
-    RSTR_UNSET_FSHARED_FLAG(s1);
-    RSTR_SET_EMBED_FLAG(s1);
-    memcpy(s1->as.ary, RSTR_PTR(s2), len);
-    RSTR_SET_EMBED_LEN(s1, len);
+  len = (size_t)RSTR_LEN(s2);
+  if (RSTR_EMBEDDABLE_P(len)) {
+    str_init_embed(s1, RSTR_PTR(s2), len);
   }
   else {
-    str_make_shared(mrb, s2, s1);
+    str_share(mrb, s2, s1);
   }
 
   return mrb_obj_value(s1);
@@ -539,7 +745,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
 static mrb_int
 str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
 {
-  char *s, *sbeg, *t;
+  const char *s, *sbeg, *t;
   struct RString *ps = mrb_str_ptr(str);
   mrb_int len = RSTRING_LEN(sub);
 
@@ -552,11 +758,12 @@ str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
   s = RSTR_PTR(ps) + pos;
   t = RSTRING_PTR(sub);
   if (len) {
+    s = char_adjust(sbeg, sbeg + RSTR_LEN(ps), s);
     while (sbeg <= s) {
       if (memcmp(s, t, len) == 0) {
         return (mrb_int)(s - RSTR_PTR(ps));
       }
-      s--;
+      s = char_backtrack(sbeg, s);
     }
     return -1;
   }
@@ -644,65 +851,17 @@ mrb_locale_from_utf8(const char *utf8, int len)
 #endif
 
 MRB_API void
-mrb_str_modify(mrb_state *mrb, struct RString *s)
+mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s)
 {
-  check_frozen(mrb, s);
-  s->flags &= ~MRB_STR_NO_UTF;
-  if (RSTR_SHARED_P(s)) {
-    mrb_shared_string *shared = s->as.heap.aux.shared;
-
-    if (shared->nofree == 0 && shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) {
-      s->as.heap.ptr = shared->ptr;
-      s->as.heap.aux.capa = shared->len;
-      RSTR_PTR(s)[s->as.heap.len] = '\0';
-      mrb_free(mrb, shared);
-    }
-    else {
-      char *ptr, *p;
-      mrb_int len;
-
-      p = RSTR_PTR(s);
-      len = s->as.heap.len;
-      if (len < RSTRING_EMBED_LEN_MAX) {
-        RSTR_SET_EMBED_FLAG(s);
-        RSTR_SET_EMBED_LEN(s, len);
-        ptr = RSTR_PTR(s);
-      }
-      else {
-        ptr = (char *)mrb_malloc(mrb, (size_t)len + 1);
-        s->as.heap.ptr = ptr;
-        s->as.heap.aux.capa = len;
-      }
-      if (p) {
-        memcpy(ptr, p, len);
-      }
-      ptr[len] = '\0';
-      str_decref(mrb, shared);
-    }
-    RSTR_UNSET_SHARED_FLAG(s);
-    return;
-  }
-  if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) {
-    char *p = s->as.heap.ptr;
-    mrb_int len = s->as.heap.len;
+  mrb_check_frozen(mrb, s);
+  str_modify_keep_ascii(mrb, s);
+}
 
-    RSTR_UNSET_FSHARED_FLAG(s);
-    RSTR_UNSET_NOFREE_FLAG(s);
-    RSTR_UNSET_FSHARED_FLAG(s);
-    if (len < RSTRING_EMBED_LEN_MAX) {
-      RSTR_SET_EMBED_FLAG(s);
-      RSTR_SET_EMBED_LEN(s, len);
-    }
-    else {
-      s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
-      s->as.heap.aux.capa = len;
-    }
-    if (p) {
-      memcpy(RSTR_PTR(s), p, len);
-    }
-    RSTR_PTR(s)[len] = '\0';
-    return;
-  }
+MRB_API void
+mrb_str_modify(mrb_state *mrb, struct RString *s)
+{
+  mrb_str_modify_keep_ascii(mrb, s);
+  RSTR_UNSET_ASCII_FLAG(s);
 }
 
 MRB_API mrb_value
@@ -731,14 +890,8 @@ mrb_str_to_cstr(mrb_state *mrb, mrb_value str0)
 {
   struct RString *s;
 
-  if (!mrb_string_p(str0)) {
-    mrb_raise(mrb, E_TYPE_ERROR, "expected String");
-  }
-
+  check_null_byte(mrb, str0);
   s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0));
-  if ((strlen(RSTR_PTR(s)) ^ RSTR_LEN(s)) != 0) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
-  }
   return RSTR_PTR(s);
 }
 
@@ -826,13 +979,13 @@ mrb_str_times(mrb_state *mrb, mrb_value self)
   if (times < 0) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
   }
-  if (times && MRB_INT_MAX / times < RSTRING_LEN(self)) {
+  if (times && MRB_SSIZE_MAX / times < RSTRING_LEN(self)) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big");
   }
 
   len = RSTRING_LEN(self)*times;
   str2 = str_new(mrb, 0, len);
-  str_with_class(mrb, str2, self);
+  str_with_class(str2, self);
   p = RSTR_PTR(str2);
   if (len > 0) {
     n = RSTRING_LEN(self);
@@ -844,6 +997,7 @@ mrb_str_times(mrb_state *mrb, mrb_value self)
     memcpy(p + n, p, len-n);
   }
   p[RSTR_LEN(str2)] = '\0';
+  RSTR_COPY_ASCII_FLAG(str2, mrb_str_ptr(self));
 
   return mrb_obj_value(str2);
 }
@@ -907,26 +1061,11 @@ mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2)
 static mrb_value
 mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
 {
-  mrb_value str2;
+  mrb_value str2 = mrb_get_arg1(mrb);
   mrb_int result;
 
-  mrb_get_args(mrb, "o", &str2);
   if (!mrb_string_p(str2)) {
-    if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_s"))) {
-      return mrb_nil_value();
-    }
-    else if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "<=>"))) {
-      return mrb_nil_value();
-    }
-    else {
-      mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1);
-
-      if (mrb_nil_p(tmp)) return mrb_nil_value();
-      if (!mrb_fixnum_p(tmp)) {
-        return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp);
-      }
-      result = -mrb_fixnum(tmp);
-    }
+    return mrb_nil_value();
   }
   else {
     result = mrb_str_cmp(mrb, str1, str2);
@@ -966,14 +1105,11 @@ mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2)
 static mrb_value
 mrb_str_equal_m(mrb_state *mrb, mrb_value str1)
 {
-  mrb_value str2;
-
-  mrb_get_args(mrb, "o", &str2);
+  mrb_value str2 = mrb_get_arg1(mrb);
 
   return mrb_bool_value(mrb_str_equal(mrb, str1, str2));
 }
 /* ---------------------------------- */
-mrb_value mrb_mod_to_s(mrb_state *mrb, mrb_value klass);
 
 MRB_API mrb_value
 mrb_str_to_str(mrb_state *mrb, mrb_value str)
@@ -981,6 +1117,8 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str)
   switch (mrb_type(str)) {
   case MRB_TT_STRING:
     return str;
+  case MRB_TT_SYMBOL:
+    return mrb_sym_str(mrb, mrb_symbol(str));
   case MRB_TT_FIXNUM:
     return mrb_fixnum_to_str(mrb, str, 10);
   case MRB_TT_CLASS:
@@ -991,6 +1129,7 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str)
   }
 }
 
+/* obslete: use RSTRING_PTR() */
 MRB_API const char*
 mrb_string_value_ptr(mrb_state *mrb, mrb_value str)
 {
@@ -998,6 +1137,7 @@ mrb_string_value_ptr(mrb_state *mrb, mrb_value str)
   return RSTRING_PTR(str);
 }
 
+/* obslete: use RSTRING_LEN() */
 MRB_API mrb_int
 mrb_string_value_len(mrb_state *mrb, mrb_value ptr)
 {
@@ -1005,76 +1145,101 @@ mrb_string_value_len(mrb_state *mrb, mrb_value ptr)
   return RSTRING_LEN(ptr);
 }
 
-void
-mrb_noregexp(mrb_state *mrb, mrb_value self)
-{
-  mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented");
-}
-
-void
-mrb_regexp_check(mrb_state *mrb, mrb_value obj)
-{
-  if (mrb_regexp_p(mrb, obj)) {
-    mrb_noregexp(mrb, obj);
-  }
-}
-
 MRB_API mrb_value
 mrb_str_dup(mrb_state *mrb, mrb_value str)
 {
   struct RString *s = mrb_str_ptr(str);
   struct RString *dup = str_new(mrb, 0, 0);
 
-  str_with_class(mrb, dup, str);
+  str_with_class(dup, str);
   return str_replace(mrb, dup, s);
 }
 
-static mrb_value
-mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx)
-{
-  mrb_int idx;
+enum str_convert_range {
+  /* `beg` and `len` are byte unit in `0 ... str.bytesize` */
+  STR_BYTE_RANGE_CORRECTED = 1,
 
-  mrb_regexp_check(mrb, indx);
-  switch (mrb_type(indx)) {
-    case MRB_TT_FIXNUM:
-      idx = mrb_fixnum(indx);
+  /* `beg` and `len` are char unit in any range */
+  STR_CHAR_RANGE = 2,
 
-num_index:
-      str = str_substr(mrb, str, idx, 1);
-      if (!mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value();
-      return str;
+  /* `beg` and `len` are char unit in `0 ... str.size` */
+  STR_CHAR_RANGE_CORRECTED = 3,
 
-    case MRB_TT_STRING:
-      if (str_index_str(mrb, str, indx, 0) != -1)
-        return mrb_str_dup(mrb, indx);
-      return mrb_nil_value();
+  /* `beg` is out of range */
+  STR_OUT_OF_RANGE = -1
+};
 
-    case MRB_TT_RANGE:
-      goto range_arg;
+static enum str_convert_range
+str_convert_range(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_int *beg, mrb_int *len)
+{
+  if (!mrb_undef_p(alen)) {
+    *beg = mrb_int(mrb, indx);
+    *len = mrb_int(mrb, alen);
+    return STR_CHAR_RANGE;
+  }
+  else {
+    switch (mrb_type(indx)) {
+      case MRB_TT_FIXNUM:
+        *beg = mrb_fixnum(indx);
+        *len = 1;
+        return STR_CHAR_RANGE;
 
-    default:
-      indx = mrb_Integer(mrb, indx);
-      if (mrb_nil_p(indx)) {
-      range_arg:
-        {
-          mrb_int beg, len;
-
-          len = RSTRING_CHAR_LEN(str);
-          switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) {
-          case 1:
-            return str_subseq(mrb, str, beg, len);
-          case 2:
-            return mrb_nil_value();
+      case MRB_TT_STRING:
+        *beg = str_index_str(mrb, str, indx, 0);
+        if (*beg < 0) { break; }
+        *len = RSTRING_LEN(indx);
+        return STR_BYTE_RANGE_CORRECTED;
+
+      case MRB_TT_RANGE:
+        goto range_arg;
+
+      default:
+        indx = mrb_to_int(mrb, indx);
+        if (mrb_fixnum_p(indx)) {
+          *beg = mrb_fixnum(indx);
+          *len = 1;
+          return STR_CHAR_RANGE;
+        }
+range_arg:
+        *len = RSTRING_CHAR_LEN(str);
+        switch (mrb_range_beg_len(mrb, indx, beg, len, *len, TRUE)) {
+          case MRB_RANGE_OK:
+            return STR_CHAR_RANGE_CORRECTED;
+          case MRB_RANGE_OUT:
+            return STR_OUT_OF_RANGE;
           default:
             break;
-          }
         }
+
         mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum");
+    }
+  }
+  return STR_OUT_OF_RANGE;
+}
+
+static mrb_value
+mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen)
+{
+  mrb_int beg, len;
+
+  switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) {
+    case STR_CHAR_RANGE_CORRECTED:
+      return str_subseq(mrb, str, beg, len);
+    case STR_CHAR_RANGE:
+      str = str_substr(mrb, str, beg, len);
+      if (mrb_undef_p(alen) && !mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value();
+      return str;
+    case STR_BYTE_RANGE_CORRECTED:
+      if (mrb_string_p(indx)) {
+        return mrb_str_dup(mrb, indx);
       }
-      idx = mrb_fixnum(indx);
-      goto num_index;
+      else {
+        return mrb_str_byte_subseq(mrb, str, beg, len);
+      }
+    case STR_OUT_OF_RANGE:
+    default:
+      return mrb_nil_value();
   }
-  return mrb_nil_value();    /* not reached */
 }
 
 /* 15.2.10.5.6  */
@@ -1084,8 +1249,6 @@ num_index:
  *     str[fixnum]                 => fixnum or nil
  *     str[fixnum, fixnum]         => new_str or nil
  *     str[range]                  => new_str or nil
- *     str[regexp]                 => new_str or nil
- *     str[regexp, fixnum]         => new_str or nil
  *     str[other_str]              => new_str or nil
  *     str.slice(fixnum)           => fixnum or nil
  *     str.slice(fixnum, fixnum)   => new_str or nil
@@ -1121,20 +1284,198 @@ static mrb_value
 mrb_str_aref_m(mrb_state *mrb, mrb_value str)
 {
   mrb_value a1, a2;
-  mrb_int argc;
 
-  argc = mrb_get_args(mrb, "o|o", &a1, &a2);
-  if (argc == 2) {
-    mrb_int n1, n2;
+  if (mrb_get_args(mrb, "o|o", &a1, &a2) == 1) {
+    a2 = mrb_undef_value();
+  }
+
+  return mrb_str_aref(mrb, str, a1, a2);
+}
+
+static mrb_noreturn void
+str_out_of_index(mrb_state *mrb, mrb_value index)
+{
+  mrb_raisef(mrb, E_INDEX_ERROR, "index %v out of string", index);
+}
+
+static mrb_value
+str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb_value rep)
+{
+  const mrb_int shrink_threshold = 256;
+  struct RString *str = mrb_str_ptr(src);
+  mrb_int len = RSTR_LEN(str);
+  mrb_int replen, newlen;
+  char *strp;
+
+  if (end > len) { end = len; }
+
+  if (pos < 0 || pos > len) {
+    str_out_of_index(mrb, mrb_fixnum_value(pos));
+  }
+
+  replen = (mrb_nil_p(rep) ? 0 : RSTRING_LEN(rep));
+  newlen = replen + len - (end - pos);
+
+  if (newlen >= MRB_SSIZE_MAX || newlen < replen /* overflowed */) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "string size too big");
+  }
+
+  mrb_str_modify(mrb, str);
+
+  if (len < newlen) {
+    resize_capa(mrb, str, newlen);
+  }
+
+  strp = RSTR_PTR(str);
+
+  memmove(strp + newlen - (len - end), strp + end, len - end);
+  if (!mrb_nil_p(rep)) {
+    memmove(strp + pos, RSTRING_PTR(rep), replen);
+  }
+  RSTR_SET_LEN(str, newlen);
+  strp[newlen] = '\0';
+
+  if (len - newlen >= shrink_threshold) {
+    resize_capa(mrb, str, newlen);
+  }
+
+  return src;
+}
+
+#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))
+
+static mrb_value
+str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect)
+{
+  const char *p, *pend;
+  char buf[4];  /* `\x??` or UTF-8 character */
+  mrb_value result = mrb_str_new_lit(mrb, "\"");
+#ifdef MRB_UTF8_STRING
+  uint32_t ascii_flag = MRB_STR_ASCII;
+#endif
+
+  p = RSTRING_PTR(str); pend = RSTRING_END(str);
+  for (;p < pend; p++) {
+    unsigned char c, cc;
+#ifdef MRB_UTF8_STRING
+    if (inspect) {
+      mrb_int clen = mrb_utf8len(p, pend);
+      if (clen > 1) {
+        mrb_int i;
+
+        for (i=0; i<clen; i++) {
+          buf[i] = p[i];
+        }
+        mrb_str_cat(mrb, result, buf, clen);
+        p += clen-1;
+        ascii_flag = 0;
+        continue;
+      }
+    }
+#endif
+    c = *p;
+    if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) {
+      buf[0] = '\\'; buf[1] = c;
+      mrb_str_cat(mrb, result, buf, 2);
+      continue;
+    }
+    if (ISPRINT(c)) {
+      buf[0] = c;
+      mrb_str_cat(mrb, result, buf, 1);
+      continue;
+    }
+    switch (c) {
+      case '\n': cc = 'n'; break;
+      case '\r': cc = 'r'; break;
+      case '\t': cc = 't'; break;
+      case '\f': cc = 'f'; break;
+      case '\013': cc = 'v'; break;
+      case '\010': cc = 'b'; break;
+      case '\007': cc = 'a'; break;
+      case 033: cc = 'e'; break;
+      default: cc = 0; break;
+    }
+    if (cc) {
+      buf[0] = '\\';
+      buf[1] = (char)cc;
+      mrb_str_cat(mrb, result, buf, 2);
+      continue;
+    }
+    else {
+      buf[0] = '\\';
+      buf[1] = 'x';
+      buf[3] = mrb_digitmap[c % 16]; c /= 16;
+      buf[2] = mrb_digitmap[c % 16];
+      mrb_str_cat(mrb, result, buf, 4);
+      continue;
+    }
+  }
+  mrb_str_cat_lit(mrb, result, "\"");
+#ifdef MRB_UTF8_STRING
+  if (inspect) {
+    mrb_str_ptr(str)->flags |= ascii_flag;
+    mrb_str_ptr(result)->flags |= ascii_flag;
+  }
+  else {
+    RSTR_SET_ASCII_FLAG(mrb_str_ptr(result));
+  }
+#endif
+
+  return result;
+}
+
+static void
+mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_value replace)
+{
+  mrb_int beg, len, charlen;
 
-    mrb_regexp_check(mrb, a1);
-    mrb_get_args(mrb, "ii", &n1, &n2);
-    return str_substr(mrb, str, n1, n2);
+  mrb_to_str(mrb, replace);
+
+  switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) {
+    case STR_OUT_OF_RANGE:
+    default:
+      mrb_raise(mrb, E_INDEX_ERROR, "string not matched");
+    case STR_CHAR_RANGE:
+      if (len < 0) {
+        mrb_raisef(mrb, E_INDEX_ERROR, "negative length %v", alen);
+      }
+      charlen = RSTRING_CHAR_LEN(str);
+      if (beg < 0) { beg += charlen; }
+      if (beg < 0 || beg > charlen) { str_out_of_index(mrb, indx); }
+      /* fall through */
+    case STR_CHAR_RANGE_CORRECTED:
+      str_range_to_bytes(str, &beg, &len);
+      /* fall through */
+    case STR_BYTE_RANGE_CORRECTED:
+      str_replace_partial(mrb, str, beg, beg + len, replace);
   }
-  if (argc != 1) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1)", mrb_fixnum_value(argc));
+}
+
+/*
+ * call-seq:
+ *    str[fixnum] = replace
+ *    str[fixnum, fixnum] = replace
+ *    str[range] = replace
+ *    str[other_str] = replace
+ *
+ * Modify +self+ by replacing the content of +self+.
+ * The portion of the string affected is determined using the same criteria as +String#[]+.
+ */
+static mrb_value
+mrb_str_aset_m(mrb_state *mrb, mrb_value str)
+{
+  mrb_value indx, alen, replace;
+
+  switch (mrb_get_args(mrb, "oo|S!", &indx, &alen, &replace)) {
+    case 2:
+      replace = alen;
+      alen = mrb_undef_value();
+      break;
+    case 3:
+      break;
   }
-  return mrb_str_aref(mrb, str, a1);
+  mrb_str_aset(mrb, str, indx, alen, replace);
+  return str;
 }
 
 /* 15.2.10.5.8  */
@@ -1157,7 +1498,7 @@ mrb_str_capitalize_bang(mrb_state *mrb, mrb_value str)
   mrb_bool modify = FALSE;
   struct RString *s = mrb_str_ptr(str);
 
-  mrb_str_modify(mrb, s);
+  mrb_str_modify_keep_ascii(mrb, s);
   if (RSTR_LEN(s) == 0 || !RSTR_PTR(s)) return mrb_nil_value();
   p = RSTR_PTR(s); pend = RSTR_PTR(s) + RSTR_LEN(s);
   if (ISLOWER(*p)) {
@@ -1216,7 +1557,7 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str)
   struct RString *s = mrb_str_ptr(str);
 
   argc = mrb_get_args(mrb, "|S", &rs);
-  mrb_str_modify(mrb, s);
+  mrb_str_modify_keep_ascii(mrb, s);
   len = RSTR_LEN(s);
   if (argc == 0) {
     if (len == 0) return mrb_nil_value();
@@ -1278,9 +1619,8 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str)
  *     str.chomp(separator="\n")   => new_str
  *
  *  Returns a new <code>String</code> with the given record separator removed
- *  from the end of <i>str</i> (if present). If <code>$/</code> has not been
- *  changed from the default Ruby record separator, then <code>chomp</code> also
- *  removes carriage return characters (that is it will remove <code>\n</code>,
+ *  from the end of <i>str</i> (if present). <code>chomp</code> also removes
+ *  carriage return characters (that is it will remove <code>\n</code>,
  *  <code>\r</code>, and <code>\r\n</code>).
  *
  *     "hello".chomp            #=> "hello"
@@ -1315,14 +1655,14 @@ mrb_str_chop_bang(mrb_state *mrb, mrb_value str)
 {
   struct RString *s = mrb_str_ptr(str);
 
-  mrb_str_modify(mrb, s);
+  mrb_str_modify_keep_ascii(mrb, s);
   if (RSTR_LEN(s) > 0) {
     mrb_int len;
 #ifdef MRB_UTF8_STRING
     const char* t = RSTR_PTR(s), *p = t;
     const char* e = p + RSTR_LEN(s);
     while (p<e) {
-      mrb_int clen = utf8len(p, e);
+      mrb_int clen = mrb_utf8len(p, e);
       if (p + clen>=e) break;
       p += clen;
     }
@@ -1384,7 +1724,7 @@ mrb_str_downcase_bang(mrb_state *mrb, mrb_value str)
   mrb_bool modify = FALSE;
   struct RString *s = mrb_str_ptr(str);
 
-  mrb_str_modify(mrb, s);
+  mrb_str_modify_keep_ascii(mrb, s);
   p = RSTR_PTR(s);
   pend = RSTR_PTR(s) + RSTR_LEN(s);
   while (p < pend) {
@@ -1448,11 +1788,10 @@ mrb_str_empty_p(mrb_state *mrb, mrb_value self)
 static mrb_value
 mrb_str_eql(mrb_state *mrb, mrb_value self)
 {
-  mrb_value str2;
+  mrb_value str2 = mrb_get_arg1(mrb);
   mrb_bool eql_p;
 
-  mrb_get_args(mrb, "o", &str2);
-  eql_p = (mrb_type(str2) == MRB_TT_STRING) && str_eql(mrb, self, str2);
+  eql_p = (mrb_string_p(str2)) && str_eql(mrb, self, str2);
 
   return mrb_bool_value(eql_p);
 }
@@ -1521,71 +1860,36 @@ mrb_str_include(mrb_state *mrb, mrb_value self)
 /*
  *  call-seq:
  *     str.index(substring [, offset])   => fixnum or nil
- *     str.index(fixnum [, offset])      => fixnum or nil
- *     str.index(regexp [, offset])      => fixnum or nil
  *
  *  Returns the index of the first occurrence of the given
- *  <i>substring</i>,
- *  character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>.
- *  Returns
- *  <code>nil</code> if not found.
+ *  <i>substring</i>. Returns <code>nil</code> if not found.
  *  If the second parameter is present, it
  *  specifies the position in the string to begin the search.
  *
- *     "hello".index('e')             #=> 1
+ *     "hello".index('l')             #=> 2
  *     "hello".index('lo')            #=> 3
  *     "hello".index('a')             #=> nil
- *     "hello".index(101)             #=> 1(101=0x65='e')
- *     "hello".index(/[aeiou]/, -3)   #=> 4
+ *     "hello".index('l', -2)         #=> 3
  */
 static mrb_value
 mrb_str_index_m(mrb_state *mrb, mrb_value str)
 {
-  mrb_value *argv;
-  mrb_int argc;
   mrb_value sub;
-  mrb_int pos, clen;
+  mrb_int pos;
 
-  mrb_get_args(mrb, "*!", &argv, &argc);
-  if (argc == 2) {
-    mrb_get_args(mrb, "oi", &sub, &pos);
-  }
-  else {
+  if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
     pos = 0;
-    if (argc > 0)
-      sub = argv[0];
-    else
-      sub = mrb_nil_value();
   }
-  mrb_regexp_check(mrb, sub);
-  clen = RSTRING_CHAR_LEN(str);
-  if (pos < 0) {
+  else if (pos < 0) {
+    mrb_int clen = RSTRING_CHAR_LEN(str);
     pos += clen;
     if (pos < 0) {
       return mrb_nil_value();
     }
   }
-  if (pos > clen) return mrb_nil_value();
-  pos = chars2bytes(str, 0, pos);
-
-  switch (mrb_type(sub)) {
-    default: {
-      mrb_value tmp;
-
-      tmp = mrb_check_string_type(mrb, sub);
-      if (mrb_nil_p(tmp)) {
-        mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub);
-      }
-      sub = tmp;
-    }
-    /* fall through */
-    case MRB_TT_STRING:
-      pos = str_index_str(mrb, str, sub, pos);
-      break;
-  }
+  pos = str_index_str_by_char(mrb, str, sub, pos);
 
   if (pos == -1) return mrb_nil_value();
-  pos = bytes2chars(RSTRING_PTR(str), pos);
   BYTES_ALIGN_CHECK(pos);
   return mrb_fixnum_value(pos);
 }
@@ -1658,15 +1962,10 @@ mrb_str_intern(mrb_state *mrb, mrb_value self)
 MRB_API mrb_value
 mrb_obj_as_string(mrb_state *mrb, mrb_value obj)
 {
-  mrb_value str;
-
   if (mrb_string_p(obj)) {
     return obj;
   }
-  str = mrb_funcall(mrb, obj, "to_s", 0);
-  if (!mrb_string_p(str))
-    return mrb_any_to_s(mrb, obj);
-  return str;
+  return mrb_str_to_str(mrb, obj);
 }
 
 MRB_API mrb_value
@@ -1699,6 +1998,18 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
   return mrb_obj_value(p_str);
 }
 
+static inline void
+str_reverse(char *p, char *e)
+{
+  char c;
+
+  while (p < e) {
+    c = *p;
+    *p++ = *e;
+    *e-- = c;
+  }
+}
+
 /* 15.2.10.5.30 */
 /*
  *  call-seq:
@@ -1709,53 +2020,38 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
 static mrb_value
 mrb_str_reverse_bang(mrb_state *mrb, mrb_value str)
 {
+  struct RString *s = mrb_str_ptr(str);
+  char *p, *e;
+
 #ifdef MRB_UTF8_STRING
   mrb_int utf8_len = RSTRING_CHAR_LEN(str);
-  mrb_int len = RSTRING_LEN(str);
-
-  if (utf8_len == len) goto bytes;
-  if (utf8_len > 1) {
-    char *buf;
-    char *p, *e, *r;
-
-    mrb_str_modify(mrb, mrb_str_ptr(str));
-    len = RSTRING_LEN(str);
-    buf = (char*)mrb_malloc(mrb, (size_t)len);
-    p = buf;
-    e = buf + len;
-
-    memcpy(buf, RSTRING_PTR(str), len);
-    r = RSTRING_PTR(str) + len;
+  mrb_int len = RSTR_LEN(s);
 
+  if (utf8_len < 2) return str;
+  if (utf8_len < len) {
+    mrb_str_modify(mrb, s);
+    p = RSTR_PTR(s);
+    e = p + RSTR_LEN(s);
     while (p<e) {
-      mrb_int clen = utf8len(p, e);
-      r -= clen;
-      memcpy(r, p, clen);
+      mrb_int clen = mrb_utf8len(p, e);
+      str_reverse(p, p + clen - 1);
       p += clen;
     }
-    mrb_free(mrb, buf);
+    goto bytes;
   }
-  return str;
-
- bytes:
 #endif
-  {
-    struct RString *s = mrb_str_ptr(str);
-    char *p, *e;
-    char c;
 
+  if (RSTR_LEN(s) > 1) {
     mrb_str_modify(mrb, s);
-    if (RSTR_LEN(s) > 1) {
-      p = RSTR_PTR(s);
-      e = p + RSTR_LEN(s) - 1;
-      while (p < e) {
-      c = *p;
-      *p++ = *e;
-      *e-- = c;
-      }
-    }
-    return str;
+    goto bytes;
   }
+  return str;
+
+ bytes:
+  p = RSTR_PTR(s);
+  e = p + RSTR_LEN(s) - 1;
+  str_reverse(p, e);
+  return str;
 }
 
 /* ---------------------------------- */
@@ -1779,73 +2075,43 @@ mrb_str_reverse(mrb_state *mrb, mrb_value str)
 /* 15.2.10.5.31 */
 /*
  *  call-seq:
- *     str.rindex(substring [, fixnum])   => fixnum or nil
- *     str.rindex(fixnum [, fixnum])   => fixnum or nil
- *     str.rindex(regexp [, fixnum])   => fixnum or nil
+ *     str.rindex(substring [, offset])   => fixnum or nil
  *
- *  Returns the index of the last occurrence of the given <i>substring</i>,
- *  character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. Returns
- *  <code>nil</code> if not found. If the second parameter is present, it
- *  specifies the position in the string to end the search---characters beyond
- *  this point will not be considered.
+ *  Returns the index of the last occurrence of the given <i>substring</i>.
+ *  Returns <code>nil</code> if not found. If the second parameter is
+ *  present, it specifies the position in the string to end the
+ *  search---characters beyond this point will not be considered.
  *
  *     "hello".rindex('e')             #=> 1
  *     "hello".rindex('l')             #=> 3
  *     "hello".rindex('a')             #=> nil
- *     "hello".rindex(101)             #=> 1
- *     "hello".rindex(/[aeiou]/, -2)   #=> 1
+ *     "hello".rindex('l', 2)          #=> 2
  */
 static mrb_value
 mrb_str_rindex(mrb_state *mrb, mrb_value str)
 {
-  mrb_value *argv;
-  mrb_int argc;
   mrb_value sub;
   mrb_int pos, len = RSTRING_CHAR_LEN(str);
 
-  mrb_get_args(mrb, "*!", &argv, &argc);
-  if (argc == 2) {
-    mrb_get_args(mrb, "oi", &sub, &pos);
+  if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
+    pos = len;
+  }
+  else {
     if (pos < 0) {
       pos += len;
       if (pos < 0) {
-        mrb_regexp_check(mrb, sub);
         return mrb_nil_value();
       }
     }
     if (pos > len) pos = len;
   }
-  else {
-    pos = len;
-    if (argc > 0)
-      sub = argv[0];
-    else
-      sub = mrb_nil_value();
-  }
   pos = chars2bytes(str, 0, pos);
-  mrb_regexp_check(mrb, sub);
-
-  switch (mrb_type(sub)) {
-    default: {
-      mrb_value tmp;
-
-      tmp = mrb_check_string_type(mrb, sub);
-      if (mrb_nil_p(tmp)) {
-        mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub);
-      }
-      sub = tmp;
-    }
-     /* fall through */
-    case MRB_TT_STRING:
-      pos = str_rindex(mrb, str, sub, pos);
-      if (pos >= 0) {
-        pos = bytes2chars(RSTRING_PTR(str), pos);
-        BYTES_ALIGN_CHECK(pos);
-        return mrb_fixnum_value(pos);
-      }
-      break;
-
-  } /* end of switch (TYPE(sub)) */
+  pos = str_rindex(mrb, str, sub, pos);
+  if (pos >= 0) {
+    pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos);
+    BYTES_ALIGN_CHECK(pos);
+    return mrb_fixnum_value(pos);
+  }
   return mrb_nil_value();
 }
 
@@ -1853,23 +2119,18 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str)
 
 /*
  *  call-seq:
- *     str.split(pattern="\n", [limit])   => anArray
+ *     str.split(separator=nil, [limit])   => anArray
  *
  *  Divides <i>str</i> into substrings based on a delimiter, returning an array
  *  of these substrings.
  *
- *  If <i>pattern</i> is a <code>String</code>, then its contents are used as
- *  the delimiter when splitting <i>str</i>. If <i>pattern</i> is a single
+ *  If <i>separator</i> is a <code>String</code>, then its contents are used as
+ *  the delimiter when splitting <i>str</i>. If <i>separator</i> is a single
  *  space, <i>str</i> is split on whitespace, with leading whitespace and runs
  *  of contiguous whitespace characters ignored.
  *
- *  If <i>pattern</i> is a <code>Regexp</code>, <i>str</i> is divided where the
- *  pattern matches. Whenever the pattern matches a zero-length string,
- *  <i>str</i> is split into individual characters.
- *
- *  If <i>pattern</i> is omitted, the value of <code>$;</code> is used.  If
- *  <code>$;</code> is <code>nil</code> (which is the default), <i>str</i> is
- *  split on whitespace as if ' ' were specified.
+ *  If <i>separator</i> is omitted or <code>nil</code> (which is the default),
+ *  <i>str</i> is split on whitespace as if ' ' were specified.
  *
  *  If the <i>limit</i> parameter is omitted, trailing null fields are
  *  suppressed. If <i>limit</i> is a positive number, at most that number of
@@ -1880,9 +2141,6 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str)
  *
  *     " now's  the time".split        #=> ["now's", "the", "time"]
  *     " now's  the time".split(' ')   #=> ["now's", "the", "time"]
- *     " now's  the time".split(/ /)   #=> ["", "now's", "", "the", "time"]
- *     "hello".split(//)               #=> ["h", "e", "l", "l", "o"]
- *     "hello".split(//, 3)            #=> ["h", "e", "llo"]
  *
  *     "mellow yellow".split("ello")   #=> ["m", "w y", "w"]
  *     "1,2,,3,4,,".split(',')         #=> ["1", "2", "", "3", "4"]
@@ -1895,7 +2153,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
 {
   mrb_int argc;
   mrb_value spat = mrb_nil_value();
-  enum {awk, string, regexp} split_type = string;
+  enum {awk, string} split_type = string;
   mrb_int i = 0;
   mrb_int beg;
   mrb_int end;
@@ -1917,16 +2175,11 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
   if (argc == 0 || mrb_nil_p(spat)) {
     split_type = awk;
   }
-  else {
-    if (mrb_string_p(spat)) {
-      split_type = string;
-      if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
-          split_type = awk;
-      }
-    }
-    else {
-      mrb_noregexp(mrb, str);
-    }
+  else if (!mrb_string_p(spat)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "expected String");
+  }
+  else if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
+    split_type = awk;
   }
 
   result = mrb_ary_new(mrb);
@@ -1952,7 +2205,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
         }
       }
       else if (ISSPACE(c)) {
-        mrb_ary_push(mrb, result, byte_subseq(mrb, str, beg, end-beg));
+        mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, beg, end-beg));
         mrb_gc_arena_restore(mrb, ai);
         skip = TRUE;
         beg = idx;
@@ -1963,7 +2216,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
       }
     }
   }
-  else if (split_type == string) {
+  else {                        /* split_type == string */
     mrb_int str_len = RSTRING_LEN(str);
     mrb_int pat_len = RSTRING_LEN(spat);
     mrb_int idx = 0;
@@ -1977,22 +2230,19 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
       else {
         end = chars2bytes(str, idx, 1);
       }
-      mrb_ary_push(mrb, result, byte_subseq(mrb, str, idx, end));
+      mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, idx, end));
       mrb_gc_arena_restore(mrb, ai);
       idx += end + pat_len;
       if (lim_p && lim <= ++i) break;
     }
     beg = idx;
   }
-  else {
-    mrb_noregexp(mrb, str);
-  }
   if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) {
     if (RSTRING_LEN(str) == beg) {
       tmp = mrb_str_new_empty(mrb, str);
     }
     else {
-      tmp = byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg);
+      tmp = mrb_str_byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg);
     }
     mrb_ary_push(mrb, result, tmp);
   }
@@ -2006,7 +2256,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
   return result;
 }
 
-static mrb_value
+mrb_value
 mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base, int badcheck)
 {
   const char *p = str;
@@ -2090,7 +2340,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base,
       break;
     default:
       if (base < 2 || 36 < base) {
-        mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base));
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base);
       }
       break;
   } /* end of switch (base) { */
@@ -2117,7 +2367,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base,
     if (*(p - 1) == '0')
       p--;
   }
-  if (p == pend) {
+  if (p == pend || *p == '_') {
     if (badcheck) goto bad;
     return mrb_fixnum_value(0);
   }
@@ -2150,16 +2400,16 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base,
       else
 #endif
       {
-        mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer",
-                   mrb_str_new(mrb, str, pend-str));
+        mrb_raisef(mrb, E_RANGE_ERROR, "string (%l) too big for integer", str, pend-str);
       }
     }
   }
   val = (mrb_int)n;
   if (badcheck) {
-    if (p == str) goto bad; /* no number */
+    if (p == str) goto bad;             /* no number */
+    if (*(p - 1) == '_') goto bad;      /* trailing '_' */
     while (p<pend && ISSPACE(*p)) p++;
-    if (p<pend) goto bad;       /* trailing garbage */
+    if (p<pend) goto bad;               /* trailing garbage */
   }
 
   return mrb_fixnum_value(sign ? val : -val);
@@ -2167,8 +2417,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base,
   mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
   /* not reached */
  bad:
-  mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)",
-             mrb_inspect(mrb, mrb_str_new(mrb, str, pend-str)));
+  mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%!l)", str, pend-str);
   /* not reached */
   return mrb_fixnum_value(0);
 }
@@ -2179,23 +2428,35 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, mrb_int base, mrb_bool badchec
   return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck);
 }
 
+/* obslete: use RSTRING_CSTR() or mrb_string_cstr() */
 MRB_API const char*
 mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr)
 {
-  mrb_value str = mrb_to_str(mrb, *ptr);
-  struct RString *ps = mrb_str_ptr(str);
-  mrb_int len = mrb_str_strlen(mrb, ps);
-  char *p = RSTR_PTR(ps);
+  struct RString *ps;
+  const char *p;
+  mrb_int len;
 
-  if (!p || p[len] != '\0') {
-    if (MRB_FROZEN_P(ps)) {
-      *ptr = str = mrb_str_dup(mrb, str);
-      ps = mrb_str_ptr(str);
-    }
-    mrb_str_modify(mrb, ps);
-    return RSTR_PTR(ps);
+  check_null_byte(mrb, *ptr);
+  ps = mrb_str_ptr(*ptr);
+  p = RSTR_PTR(ps);
+  len = RSTR_LEN(ps);
+  if (p[len] == '\0') {
+    return p;
   }
-  return p;
+
+  /*
+   * Even after str_modify_keep_ascii(), NULL termination is not ensured if
+   * RSTR_SET_LEN() is used explicitly (e.g. String#delete_suffix!).
+   */
+  str_modify_keep_ascii(mrb, ps);
+  RSTR_PTR(ps)[len] = '\0';
+  return RSTR_PTR(ps);
+}
+
+MRB_API const char*
+mrb_string_cstr(mrb_state *mrb, mrb_value str)
+{
+  return mrb_string_value_cstr(mrb, &str);
 }
 
 MRB_API mrb_value
@@ -2204,7 +2465,8 @@ mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck)
   const char *s;
   mrb_int len;
 
-  s = mrb_string_value_ptr(mrb, str);
+  mrb_to_str(mrb, str);
+  s = RSTRING_PTR(str);
   len = RSTRING_LEN(str);
   return mrb_str_len_to_inum(mrb, s, len, base, badcheck);
 }
@@ -2237,94 +2499,111 @@ mrb_str_to_i(mrb_state *mrb, mrb_value self)
 
   mrb_get_args(mrb, "|i", &base);
   if (base < 0) {
-    mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base));
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base);
   }
   return mrb_str_to_inum(mrb, self, base, FALSE);
 }
 
 #ifndef MRB_WITHOUT_FLOAT
-MRB_API double
-mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck)
+double
+mrb_str_len_to_dbl(mrb_state *mrb, const char *s, size_t len, mrb_bool badcheck)
 {
+  char buf[DBL_DIG * 4 + 20];
+  const char *p = s, *p2;
+  const char *pend = p + len;
   char *end;
-  char buf[DBL_DIG * 4 + 10];
+  char *n;
+  char prev = 0;
   double d;
-
-  enum {max_width = 20};
+  mrb_bool dot = FALSE;
 
   if (!p) return 0.0;
-  while (ISSPACE(*p)) p++;
-
-  if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
-    return 0.0;
+  while (p<pend && ISSPACE(*p)) p++;
+  p2 = p;
+
+  if (pend - p > 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
+    mrb_value x;
+
+    if (!badcheck) return 0.0;
+    x = mrb_str_len_to_inum(mrb, p, pend-p, 0, badcheck);
+    if (mrb_fixnum_p(x))
+      d = (double)mrb_fixnum(x);
+    else /* if (mrb_float_p(x)) */
+      d = mrb_float(x);
+    return d;
   }
+  while (p < pend) {
+    if (!*p) {
+      if (badcheck) {
+        mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte");
+        /* not reached */
+      }
+      pend = p;
+      p = p2;
+      goto nocopy;
+    }
+    if (!badcheck && *p == ' ') {
+      pend = p;
+      p = p2;
+      goto nocopy;
+    }
+    if (*p == '_') break;
+    p++;
+  }
+  p = p2;
+  n = buf;
+  while (p < pend) {
+    char c = *p++;
+    if (c == '.') dot = TRUE;
+    if (c == '_') {
+      /* remove an underscore between digits */
+      if (n == buf || !ISDIGIT(prev) || p == pend) {
+        if (badcheck) goto bad;
+        break;
+      }
+    }
+    else if (badcheck && prev == '_' && !ISDIGIT(c)) goto bad;
+    else {
+      const char *bend = buf+sizeof(buf)-1;
+      if (n==bend) {            /* buffer overflow */
+        if (dot) break;         /* cut off remaining fractions */
+        return INFINITY;
+      }
+      *n++ = c;
+    }
+    prev = c;
+  }
+  *n = '\0';
+  p = buf;
+  pend = n;
+nocopy:
   d = mrb_float_read(p, &end);
   if (p == end) {
     if (badcheck) {
 bad:
-      mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%S)", mrb_str_new_cstr(mrb, p));
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%!s)", s);
       /* not reached */
     }
     return d;
   }
-  if (*end) {
-    char *n = buf;
-    char *e = buf + sizeof(buf) - 1;
-    char prev = 0;
-
-    while (p < end && n < e) prev = *n++ = *p++;
-    while (*p) {
-      if (*p == '_') {
-        /* remove underscores between digits */
-        if (badcheck) {
-          if (n == buf || !ISDIGIT(prev)) goto bad;
-          ++p;
-          if (!ISDIGIT(*p)) goto bad;
-        }
-        else {
-          while (*++p == '_');
-          continue;
-        }
-      }
-      prev = *p++;
-      if (n < e) *n++ = prev;
-    }
-    *n = '\0';
-    p = buf;
-
-    if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
-      return 0.0;
-    }
-
-    d = mrb_float_read(p, &end);
-    if (badcheck) {
-      if (!end || p == end) goto bad;
-      while (*end && ISSPACE(*end)) end++;
-      if (*end) goto bad;
-    }
+  if (badcheck) {
+    if (!end || p == end) goto bad;
+    while (end<pend && ISSPACE(*end)) end++;
+    if (end<pend) goto bad;
   }
   return d;
 }
 
 MRB_API double
-mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck)
+mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck)
 {
-  char *s;
-  mrb_int len;
+  return mrb_str_len_to_dbl(mrb, s, strlen(s), badcheck);
+}
 
-  mrb_to_str(mrb, str);
-  s = RSTRING_PTR(str);
-  len = RSTRING_LEN(str);
-  if (s) {
-    if (badcheck && memchr(s, '\0', len)) {
-      mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte");
-    }
-    if (s[len]) {    /* no sentinel somehow */
-      struct RString *temp_str = str_new(mrb, s, len);
-      s = RSTR_PTR(temp_str);
-    }
-  }
-  return mrb_cstr_to_dbl(mrb, s, badcheck);
+MRB_API double
+mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck)
+{
+  return mrb_str_len_to_dbl(mrb, RSTRING_PTR(str), RSTRING_LEN(str), badcheck);
 }
 
 /* 15.2.10.5.39 */
@@ -2379,7 +2658,7 @@ mrb_str_upcase_bang(mrb_state *mrb, mrb_value str)
   char *p, *pend;
   mrb_bool modify = FALSE;
 
-  mrb_str_modify(mrb, s);
+  mrb_str_modify_keep_ascii(mrb, s);
   p = RSTRING_PTR(str);
   pend = RSTRING_END(str);
   while (p < pend) {
@@ -2415,8 +2694,6 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self)
   return str;
 }
 
-#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))
-
 /*
  *  call-seq:
  *     str.dump   -> new_str
@@ -2427,113 +2704,7 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self)
 mrb_value
 mrb_str_dump(mrb_state *mrb, mrb_value str)
 {
-  mrb_int len;
-  const char *p, *pend;
-  char *q;
-  struct RString *result;
-
-  len = 2;                  /* "" */
-  p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
-  while (p < pend) {
-    unsigned char c = *p++;
-    switch (c) {
-      case '"':  case '\\':
-      case '\n': case '\r':
-      case '\t': case '\f':
-      case '\013': case '\010': case '\007': case '\033':
-        len += 2;
-        break;
-
-      case '#':
-        len += IS_EVSTR(p, pend) ? 2 : 1;
-        break;
-
-      default:
-        if (ISPRINT(c)) {
-          len++;
-        }
-        else {
-          len += 4;                /* \NNN */
-        }
-        break;
-    }
-  }
-
-  result = str_new(mrb, 0, len);
-  str_with_class(mrb, result, str);
-  p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
-  q = RSTR_PTR(result);
-  *q++ = '"';
-  while (p < pend) {
-    unsigned char c = *p++;
-
-    switch (c) {
-      case '"':
-      case '\\':
-        *q++ = '\\';
-        *q++ = c;
-        break;
-
-      case '\n':
-        *q++ = '\\';
-        *q++ = 'n';
-        break;
-
-      case '\r':
-        *q++ = '\\';
-        *q++ = 'r';
-        break;
-
-      case '\t':
-        *q++ = '\\';
-        *q++ = 't';
-        break;
-
-      case '\f':
-        *q++ = '\\';
-        *q++ = 'f';
-        break;
-
-      case '\013':
-        *q++ = '\\';
-        *q++ = 'v';
-        break;
-
-      case '\010':
-        *q++ = '\\';
-        *q++ = 'b';
-        break;
-
-      case '\007':
-        *q++ = '\\';
-        *q++ = 'a';
-        break;
-
-      case '\033':
-        *q++ = '\\';
-        *q++ = 'e';
-        break;
-
-      case '#':
-        if (IS_EVSTR(p, pend)) *q++ = '\\';
-        *q++ = '#';
-        break;
-
-      default:
-        if (ISPRINT(c)) {
-          *q++ = c;
-        }
-        else {
-          *q++ = '\\';
-          *q++ = 'x';
-          q[1] = mrb_digitmap[c % 16]; c /= 16;
-          q[0] = mrb_digitmap[c % 16];
-          q += 2;
-        }
-    }
-  }
-  *q = '"';
-  return mrb_obj_value(result);
+  return str_escape(mrb, str, FALSE);
 }
 
 MRB_API mrb_value
@@ -2552,21 +2723,21 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
 
   capa = RSTR_CAPA(s);
   total = RSTR_LEN(s)+len;
-  if (total >= MRB_INT_MAX) {
+  if (total >= MRB_SSIZE_MAX) {
   size_error:
     mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
   }
   if (capa <= total) {
     if (capa == 0) capa = 1;
     while (capa <= total) {
-      if (capa <= MRB_INT_MAX / 2) {
+      if (capa <= MRB_SSIZE_MAX / 2) {
         capa *= 2;
       }
       else {
         capa = total+1;
       }
     }
-    if (capa <= total || capa > MRB_INT_MAX) {
+    if (capa <= total || capa > MRB_SSIZE_MAX) {
       goto size_error;
     }
     resize_capa(mrb, s, capa);
@@ -2575,7 +2746,7 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
       ptr = RSTR_PTR(s) + off;
   }
   memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len);
-  mrb_assert_int_fit(size_t, total, mrb_int, MRB_INT_MAX);
+  mrb_assert_int_fit(size_t, total, mrb_ssize, MRB_SSIZE_MAX);
   RSTR_SET_LEN(s, total);
   RSTR_PTR(s)[total] = '\0';   /* sentinel */
   return str;
@@ -2584,7 +2755,7 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
 MRB_API mrb_value
 mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *ptr)
 {
-  return mrb_str_cat(mrb, str, ptr, strlen(ptr));
+  return mrb_str_cat(mrb, str, ptr, ptr ? strlen(ptr) : 0);
 }
 
 MRB_API mrb_value
@@ -2603,8 +2774,6 @@ mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2)
   return mrb_str_cat_str(mrb, str1, str2);
 }
 
-#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */
-
 /*
  * call-seq:
  *   str.inspect   -> string
@@ -2619,68 +2788,7 @@ mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2)
 mrb_value
 mrb_str_inspect(mrb_state *mrb, mrb_value str)
 {
-  const char *p, *pend;
-  char buf[CHAR_ESC_LEN + 1];
-  mrb_value result = mrb_str_new_lit(mrb, "\"");
-
-  p = RSTRING_PTR(str); pend = RSTRING_END(str);
-  for (;p < pend; p++) {
-    unsigned char c, cc;
-#ifdef MRB_UTF8_STRING
-    mrb_int clen;
-
-    clen = utf8len(p, pend);
-    if (clen > 1) {
-      mrb_int i;
-
-      for (i=0; i<clen; i++) {
-        buf[i] = p[i];
-      }
-      mrb_str_cat(mrb, result, buf, clen);
-      p += clen-1;
-      continue;
-    }
-#endif
-    c = *p;
-    if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) {
-      buf[0] = '\\'; buf[1] = c;
-      mrb_str_cat(mrb, result, buf, 2);
-      continue;
-    }
-    if (ISPRINT(c)) {
-      buf[0] = c;
-      mrb_str_cat(mrb, result, buf, 1);
-      continue;
-    }
-    switch (c) {
-      case '\n': cc = 'n'; break;
-      case '\r': cc = 'r'; break;
-      case '\t': cc = 't'; break;
-      case '\f': cc = 'f'; break;
-      case '\013': cc = 'v'; break;
-      case '\010': cc = 'b'; break;
-      case '\007': cc = 'a'; break;
-      case 033: cc = 'e'; break;
-      default: cc = 0; break;
-    }
-    if (cc) {
-      buf[0] = '\\';
-      buf[1] = (char)cc;
-      mrb_str_cat(mrb, result, buf, 2);
-      continue;
-    }
-    else {
-      buf[0] = '\\';
-      buf[1] = 'x';
-      buf[3] = mrb_digitmap[c % 16]; c /= 16;
-      buf[2] = mrb_digitmap[c % 16];
-      mrb_str_cat(mrb, result, buf, 4);
-      continue;
-    }
-  }
-  mrb_str_cat_lit(mrb, result, "\"");
-
-  return result;
+  return str_escape(mrb, str, TRUE);
 }
 
 /*
@@ -2706,13 +2814,119 @@ mrb_str_bytes(mrb_state *mrb, mrb_value str)
   return a;
 }
 
+/*
+ *  call-seq:
+ *     str.getbyte(index)          -> 0 .. 255
+ *
+ *  returns the <i>index</i>th byte as an integer.
+ */
+static mrb_value
+mrb_str_getbyte(mrb_state *mrb, mrb_value str)
+{
+  mrb_int pos;
+  mrb_get_args(mrb, "i", &pos);
+
+  if (pos < 0)
+    pos += RSTRING_LEN(str);
+  if (pos < 0 ||  RSTRING_LEN(str) <= pos)
+    return mrb_nil_value();
+
+  return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]);
+}
+
+/*
+ *  call-seq:
+ *     str.setbyte(index, integer) -> integer
+ *
+ *  modifies the <i>index</i>th byte as <i>integer</i>.
+ */
+static mrb_value
+mrb_str_setbyte(mrb_state *mrb, mrb_value str)
+{
+  mrb_int pos, byte;
+  mrb_int len;
+
+  mrb_get_args(mrb, "ii", &pos, &byte);
+
+  len = RSTRING_LEN(str);
+  if (pos < -len || len <= pos)
+    mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of string", pos);
+  if (pos < 0)
+    pos += len;
+
+  mrb_str_modify(mrb, mrb_str_ptr(str));
+  byte &= 0xff;
+  RSTRING_PTR(str)[pos] = (unsigned char)byte;
+  return mrb_fixnum_value((unsigned char)byte);
+}
+
+/*
+ *  call-seq:
+ *     str.byteslice(integer)           -> new_str or nil
+ *     str.byteslice(integer, integer)   -> new_str or nil
+ *     str.byteslice(range)            -> new_str or nil
+ *
+ *  Byte Reference---If passed a single Integer, returns a
+ *  substring of one byte at that position. If passed two Integer
+ *  objects, returns a substring starting at the offset given by the first, and
+ *  a length given by the second. If given a Range, a substring containing
+ *  bytes at offsets given by the range is returned. In all three cases, if
+ *  an offset is negative, it is counted from the end of <i>str</i>. Returns
+ *  <code>nil</code> if the initial offset falls outside the string, the length
+ *  is negative, or the beginning of the range is greater than the end.
+ *  The encoding of the resulted string keeps original encoding.
+ *
+ *     "hello".byteslice(1)     #=> "e"
+ *     "hello".byteslice(-1)    #=> "o"
+ *     "hello".byteslice(1, 2)  #=> "el"
+ *     "\x80\u3042".byteslice(1, 3) #=> "\u3042"
+ *     "\x03\u3042\xff".byteslice(1..3) #=> "\u3042"
+ */
+static mrb_value
+mrb_str_byteslice(mrb_state *mrb, mrb_value str)
+{
+  mrb_value a1;
+  mrb_int str_len = RSTRING_LEN(str), beg, len;
+  mrb_bool empty = TRUE;
+
+  len = mrb_get_argc(mrb);
+  switch (len) {
+  case 2:
+    mrb_get_args(mrb, "ii", &beg, &len);
+    break;
+  case 1:
+    a1 = mrb_get_arg1(mrb);
+    if (mrb_range_p(a1)) {
+      if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) {
+        return mrb_nil_value();
+      }
+    }
+    else {
+      beg = mrb_fixnum(mrb_to_int(mrb, a1));
+      len = 1;
+      empty = FALSE;
+    }
+    break;
+  default:
+    mrb_argnum_error(mrb, len, 1, 2);
+    break;
+  }
+  if (mrb_str_beg_len(str_len, &beg, &len) && (empty || len != 0)) {
+    return mrb_str_byte_subseq(mrb, str, beg, len);
+  }
+  else {
+    return mrb_nil_value();
+  }
+}
+
 /* ---------------------------*/
 void
 mrb_init_string(mrb_state *mrb)
 {
   struct RClass *s;
 
-  mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << 5), "pointer size too big for embedded string");
+  mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << MRB_STR_EMBED_LEN_BIT),
+                    "pointer size too big for embedded string");
 
   mrb->string_class = s = mrb_define_class(mrb, "String", mrb->object_class);             /* 15.2.10 */
   MRB_SET_INSTANCE_TT(s, MRB_TT_STRING);
@@ -2724,6 +2938,7 @@ mrb_init_string(mrb_state *mrb)
   mrb_define_method(mrb, s, "+",               mrb_str_plus_m,          MRB_ARGS_REQ(1)); /* 15.2.10.5.4  */
   mrb_define_method(mrb, s, "*",               mrb_str_times,           MRB_ARGS_REQ(1)); /* 15.2.10.5.5  */
   mrb_define_method(mrb, s, "[]",              mrb_str_aref_m,          MRB_ARGS_ANY());  /* 15.2.10.5.6  */
+  mrb_define_method(mrb, s, "[]=",             mrb_str_aset_m,          MRB_ARGS_ANY());
   mrb_define_method(mrb, s, "capitalize",      mrb_str_capitalize,      MRB_ARGS_NONE()); /* 15.2.10.5.7  */
   mrb_define_method(mrb, s, "capitalize!",     mrb_str_capitalize_bang, MRB_ARGS_NONE()); /* 15.2.10.5.8  */
   mrb_define_method(mrb, s, "chomp",           mrb_str_chomp,           MRB_ARGS_ANY());  /* 15.2.10.5.9  */
@@ -2737,7 +2952,7 @@ mrb_init_string(mrb_state *mrb)
 
   mrb_define_method(mrb, s, "hash",            mrb_str_hash_m,          MRB_ARGS_NONE()); /* 15.2.10.5.20 */
   mrb_define_method(mrb, s, "include?",        mrb_str_include,         MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */
-  mrb_define_method(mrb, s, "index",           mrb_str_index_m,         MRB_ARGS_ANY());  /* 15.2.10.5.22 */
+  mrb_define_method(mrb, s, "index",           mrb_str_index_m,         MRB_ARGS_ARG(1,1));  /* 15.2.10.5.22 */
   mrb_define_method(mrb, s, "initialize",      mrb_str_init,            MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */
   mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace,         MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */
   mrb_define_method(mrb, s, "intern",          mrb_str_intern,          MRB_ARGS_NONE()); /* 15.2.10.5.25 */
@@ -2761,6 +2976,10 @@ mrb_init_string(mrb_state *mrb)
   mrb_define_method(mrb, s, "upcase!",         mrb_str_upcase_bang,     MRB_ARGS_NONE()); /* 15.2.10.5.43 */
   mrb_define_method(mrb, s, "inspect",         mrb_str_inspect,         MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */
   mrb_define_method(mrb, s, "bytes",           mrb_str_bytes,           MRB_ARGS_NONE());
+
+  mrb_define_method(mrb, s, "getbyte",         mrb_str_getbyte,         MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, s, "setbyte",         mrb_str_setbyte,         MRB_ARGS_REQ(2));
+  mrb_define_method(mrb, s, "byteslice",       mrb_str_byteslice,       MRB_ARGS_ARG(1,1));
 }
 
 #ifndef MRB_WITHOUT_FLOAT
index 96ca9dd..9928487 100644 (file)
@@ -20,6 +20,22 @@ typedef struct symbol_name {
   const char *name;
 } symbol_name;
 
+#define SYMBOL_INLINE_BIT_POS       1
+#define SYMBOL_INLINE_LOWER_BIT_POS 2
+#define SYMBOL_INLINE               (1 << (SYMBOL_INLINE_BIT_POS - 1))
+#define SYMBOL_INLINE_LOWER         (1 << (SYMBOL_INLINE_LOWER_BIT_POS - 1))
+#define SYMBOL_NORMAL_SHIFT         SYMBOL_INLINE_BIT_POS
+#define SYMBOL_INLINE_SHIFT         SYMBOL_INLINE_LOWER_BIT_POS
+#ifdef MRB_ENABLE_ALL_SYMBOLS
+# define SYMBOL_INLINE_P(sym) FALSE
+# define SYMBOL_INLINE_LOWER_P(sym) FALSE
+# define sym_inline_pack(name, len) 0
+# define sym_inline_unpack(sym, buf, lenp) NULL
+#else
+# define SYMBOL_INLINE_P(sym) ((sym) & SYMBOL_INLINE)
+# define SYMBOL_INLINE_LOWER_P(sym) ((sym) & SYMBOL_INLINE_LOWER)
+#endif
+
 static void
 sym_validate_len(mrb_state *mrb, size_t len)
 {
@@ -32,16 +48,16 @@ sym_validate_len(mrb_state *mrb, size_t len)
 static const char pack_table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 
 static mrb_sym
-sym_inline_pack(const char *name, uint16_t len)
+sym_inline_pack(const char *name, size_t len)
 {
-  const int lower_length_max = (MRB_SYMBOL_BITSIZE - 2) / 5;
-  const int mix_length_max   = (MRB_SYMBOL_BITSIZE - 2) / 6;
+  const size_t lower_length_max = (MRB_SYMBOL_BIT - 2) / 5;
+  const size_t mix_length_max   = (MRB_SYMBOL_BIT - 2) / 6;
 
   char c;
   const char *p;
-  int i;
+  size_t i;
   mrb_sym sym = 0;
-  int lower = 1;
+  mrb_bool lower = TRUE;
 
   if (len > lower_length_max) return 0; /* too long */
   for (i=0; i<len; i++) {
@@ -52,9 +68,9 @@ sym_inline_pack(const char *name, uint16_t len)
     p = strchr(pack_table, (int)c);
     if (p == 0) return 0;       /* non alnum char */
     bits = (uint32_t)(p - pack_table)+1;
-    if (bits > 27) lower = 0;
+    if (bits > 27) lower = FALSE;
     if (i >= mix_length_max) break;
-    sym |= bits<<(i*6+2);
+    sym |= bits<<(i*6+SYMBOL_INLINE_SHIFT);
   }
   if (lower) {
     sym = 0;
@@ -64,24 +80,24 @@ sym_inline_pack(const char *name, uint16_t len)
       c = name[i];
       p = strchr(pack_table, (int)c);
       bits = (uint32_t)(p - pack_table)+1;
-      sym |= bits<<(i*5+2);
+      sym |= bits<<(i*5+SYMBOL_INLINE_SHIFT);
     }
-    return sym | 3;
+    return sym | SYMBOL_INLINE | SYMBOL_INLINE_LOWER;
   }
   if (len > mix_length_max) return 0;
-  return sym | 1;
+  return sym | SYMBOL_INLINE;
 }
 
 static const char*
 sym_inline_unpack(mrb_sym sym, char *buf, mrb_int *lenp)
 {
-  int bit_per_char = sym&2 ? 5 : 6;  /* all lower case if `sym&2` is true */
+  int bit_per_char = SYMBOL_INLINE_LOWER_P(sym) ? 5 : 6;
   int i;
 
-  mrb_assert(sym&1);
+  mrb_assert(SYMBOL_INLINE_P(sym));
 
   for (i=0; i<30/bit_per_char; i++) {
-    uint32_t bits = sym>>(i*bit_per_char+2) & ((1<<bit_per_char)-1);
+    uint32_t bits = sym>>(i*bit_per_char+SYMBOL_INLINE_SHIFT) & ((1<<bit_per_char)-1);
     if (bits == 0) break;
     buf[i] = pack_table[bits-1];;
   }
@@ -91,7 +107,7 @@ sym_inline_unpack(mrb_sym sym, char *buf, mrb_int *lenp)
 }
 #endif
 
-uint8_t
+static uint8_t
 symhash(const char *key, size_t len)
 {
     uint32_t hash, i;
@@ -108,30 +124,32 @@ symhash(const char *key, size_t len)
 }
 
 static mrb_sym
-find_symbol(mrb_state *mrb, const char *name, uint16_t len, uint8_t hash)
+find_symbol(mrb_state *mrb, const char *name, size_t len, uint8_t *hashp)
 {
   mrb_sym i;
   symbol_name *sname;
+  uint8_t hash;
 
-#ifndef MRB_ENABLE_ALL_SYMBOLS
   /* inline symbol */
   i = sym_inline_pack(name, len);
   if (i > 0) return i;
-#endif
+
+  hash = symhash(name, len);
+  if (hashp) *hashp = hash;
 
   i = mrb->symhash[hash];
   if (i == 0) return 0;
   do {
     sname = &mrb->symtbl[i];
     if (sname->len == len && memcmp(sname->name, name, len) == 0) {
-      return i<<1;
+      return i<<SYMBOL_NORMAL_SHIFT;
     }
     if (sname->prev == 0xff) {
       i -= 0xff;
       sname = &mrb->symtbl[i];
       while (mrb->symtbl < sname) {
         if (sname->len == len && memcmp(sname->name, name, len) == 0) {
-          return (mrb_sym)(sname - mrb->symtbl)<<1;
+          return (mrb_sym)(sname - mrb->symtbl)<<SYMBOL_NORMAL_SHIFT;
         }
         sname--;
       }
@@ -150,16 +168,17 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit)
   uint8_t hash;
 
   sym_validate_len(mrb, len);
-  hash = symhash(name, len);
-  sym = find_symbol(mrb, name, len, hash);
+  sym = find_symbol(mrb, name, len, &hash);
   if (sym > 0) return sym;
 
   /* registering a new symbol */
-  sym = ++mrb->symidx;
+  sym = mrb->symidx + 1;
   if (mrb->symcapa < sym) {
-    if (mrb->symcapa == 0) mrb->symcapa = 100;
-    else mrb->symcapa = (size_t)(mrb->symcapa * 6 / 5);
-    mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(mrb->symcapa+1));
+    size_t symcapa = mrb->symcapa;
+    if (symcapa == 0) symcapa = 100;
+    else symcapa = (size_t)(symcapa * 6 / 5);
+    mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(symcapa+1));
+    mrb->symcapa = symcapa;
   }
   sname = &mrb->symtbl[sym];
   sname->len = (uint16_t)len;
@@ -184,9 +203,9 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit)
   else {
     sname->prev = 0;
   }
-  mrb->symhash[hash] = sym;
+  mrb->symhash[hash] = mrb->symidx = sym;
 
-  return sym<<1;
+  return sym<<SYMBOL_NORMAL_SHIFT;
 }
 
 MRB_API mrb_sym
@@ -219,7 +238,7 @@ mrb_check_intern(mrb_state *mrb, const char *name, size_t len)
   mrb_sym sym;
 
   sym_validate_len(mrb, len);
-  sym = find_symbol(mrb, name, len, symhash(name, len));
+  sym = find_symbol(mrb, name, len, NULL);
   if (sym > 0) return mrb_symbol_value(sym);
   return mrb_nil_value();
 }
@@ -239,13 +258,9 @@ mrb_check_intern_str(mrb_state *mrb, mrb_value str)
 static const char*
 sym2name_len(mrb_state *mrb, mrb_sym sym, char *buf, mrb_int *lenp)
 {
-#ifndef MRB_ENABLE_ALL_SYMBOLS
-  if (sym & 1) {                /* inline packed symbol */
-    return sym_inline_unpack(sym, buf, lenp);
-  }
-#endif
+  if (SYMBOL_INLINE_P(sym)) return sym_inline_unpack(sym, buf, lenp);
 
-  sym >>= 1;
+  sym >>= SYMBOL_NORMAL_SHIFT;
   if (sym == 0 || mrb->symidx < sym) {
     if (lenp) *lenp = 0;
     return NULL;
@@ -256,7 +271,7 @@ sym2name_len(mrb_state *mrb, mrb_sym sym, char *buf, mrb_int *lenp)
 }
 
 MRB_API const char*
-mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp)
+mrb_sym_name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp)
 {
   return sym2name_len(mrb, sym, mrb->symbuf, lenp);
 }
@@ -326,7 +341,7 @@ mrb_init_symtbl(mrb_state *mrb)
 static mrb_value
 sym_to_s(mrb_state *mrb, mrb_value sym)
 {
-  return mrb_sym2str(mrb, mrb_symbol(sym));
+  return mrb_sym_str(mrb, mrb_symbol(sym));
 }
 
 /* 15.2.11.3.4  */
@@ -481,67 +496,78 @@ sym_inspect(mrb_state *mrb, mrb_value sym)
   mrb_sym id = mrb_symbol(sym);
   char *sp;
 
-  name = mrb_sym2name_len(mrb, id, &len);
+  name = mrb_sym_name_len(mrb, id, &len);
   str = mrb_str_new(mrb, 0, len+1);
   sp = RSTRING_PTR(str);
-  RSTRING_PTR(str)[0] = ':';
+  sp[0] = ':';
   memcpy(sp+1, name, len);
   mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
   if (!symname_p(name) || strlen(name) != (size_t)len) {
-    str = mrb_str_dump(mrb, str);
+    str = mrb_str_inspect(mrb, str);
     sp = RSTRING_PTR(str);
     sp[0] = ':';
     sp[1] = '"';
   }
+#ifdef MRB_UTF8_STRING
+  if (SYMBOL_INLINE_P(id)) RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+#endif
   return str;
 }
 
 MRB_API mrb_value
-mrb_sym2str(mrb_state *mrb, mrb_sym sym)
+mrb_sym_str(mrb_state *mrb, mrb_sym sym)
 {
   mrb_int len;
-  const char *name = mrb_sym2name_len(mrb, sym, &len);
+  const char *name = mrb_sym_name_len(mrb, sym, &len);
 
   if (!name) return mrb_undef_value(); /* can't happen */
-  if (sym&1) {                         /* inline symbol */
-    return mrb_str_new(mrb, name, len);
+  if (SYMBOL_INLINE_P(sym)) {
+    mrb_value str = mrb_str_new(mrb, name, len);
+    RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
+    return str;
   }
   return mrb_str_new_static(mrb, name, len);
 }
 
-MRB_API const char*
-mrb_sym2name(mrb_state *mrb, mrb_sym sym)
+static const char*
+sym_name(mrb_state *mrb, mrb_sym sym, mrb_bool dump)
 {
   mrb_int len;
-  const char *name = mrb_sym2name_len(mrb, sym, &len);
+  const char *name = mrb_sym_name_len(mrb, sym, &len);
 
   if (!name) return NULL;
-  if (symname_p(name) && strlen(name) == (size_t)len) {
+  if (strlen(name) == (size_t)len && (!dump || symname_p(name))) {
     return name;
   }
   else {
-    mrb_value str;
-    if (sym&1) {                /* inline symbol */
-      str = mrb_str_new(mrb, name, len);
-    }
-    else {
-      str = mrb_str_new_static(mrb, name, len);
-    }
+    mrb_value str = SYMBOL_INLINE_P(sym) ?
+      mrb_str_new(mrb, name, len) : mrb_str_new_static(mrb, name, len);
     str = mrb_str_dump(mrb, str);
     return RSTRING_PTR(str);
   }
 }
 
+MRB_API const char*
+mrb_sym_name(mrb_state *mrb, mrb_sym sym)
+{
+  return sym_name(mrb, sym, FALSE);
+}
+
+MRB_API const char*
+mrb_sym_dump(mrb_state *mrb, mrb_sym sym)
+{
+  return sym_name(mrb, sym, TRUE);
+}
+
 #define lesser(a,b) (((a)>(b))?(b):(a))
 
 static mrb_value
 sym_cmp(mrb_state *mrb, mrb_value s1)
 {
-  mrb_value s2;
+  mrb_value s2 = mrb_get_arg1(mrb);
   mrb_sym sym1, sym2;
 
-  mrb_get_args(mrb, "o", &s2);
-  if (mrb_type(s2) != MRB_TT_SYMBOL) return mrb_nil_value();
+  if (!mrb_symbol_p(s2)) return mrb_nil_value();
   sym1 = mrb_symbol(s1);
   sym2 = mrb_symbol(s2);
   if (sym1 == sym2) return mrb_fixnum_value(0);
index 724b153..030aa7b 100644 (file)
@@ -79,19 +79,19 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
   }
 
   /* Not found */
-  t->size++;
   if (matched_seg) {
     matched_seg->key[matched_idx] = sym;
     matched_seg->val[matched_idx] = val;
+    t->size++;
     return;
   }
 
   seg = (segment*)mrb_malloc(mrb, sizeof(segment));
-  if (!seg) return;
   seg->next = NULL;
   seg->key[0] = sym;
   seg->val[0] = val;
   t->last_len = 1;
+  t->size++;
   if (prev) {
     prev->next = seg;
   }
@@ -341,23 +341,24 @@ mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym)
 
 static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
 
-MRB_API void
-mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
+void
+mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
 {
-  iv_tbl *t;
-
-  if (MRB_FROZEN_P(obj)) {
-    mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %S", mrb_obj_value(obj));
-  }
   assign_class_name(mrb, obj, sym, v);
   if (!obj->iv) {
     obj->iv = iv_new(mrb);
   }
-  t = obj->iv;
-  iv_put(mrb, t, sym, v);
+  iv_put(mrb, obj->iv, sym, v);
   mrb_write_barrier(mrb, (struct RBasic*)obj);
 }
 
+MRB_API void
+mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
+{
+  mrb_check_frozen(mrb, obj);
+  mrb_obj_iv_set_force(mrb, obj, sym, v);
+}
+
 /* Iterates over the instance variable table. */
 MRB_API void
 mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p)
@@ -377,7 +378,7 @@ assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
 {
   if (namespace_p(obj->tt) && namespace_p(mrb_type(v))) {
     struct RObject *c = mrb_obj_ptr(v);
-    if (obj != c && ISUPPER(mrb_sym2name(mrb, sym)[0])) {
+    if (obj != c && ISUPPER(mrb_sym_name_len(mrb, sym, NULL)[0])) {
       mrb_sym id_classname = mrb_intern_lit(mrb, "__classname__");
       mrb_value o = mrb_obj_iv_get(mrb, c, id_classname);
 
@@ -387,10 +388,10 @@ assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
 
         if (mrb_nil_p(o)) {
           if ((struct RClass *)obj == mrb->object_class) {
-            mrb_obj_iv_set(mrb, c, id_classname, mrb_symbol_value(sym));
+            mrb_obj_iv_set_force(mrb, c, id_classname, mrb_symbol_value(sym));
           }
           else {
-            mrb_obj_iv_set(mrb, c, id_outer, mrb_obj_value(obj));
+            mrb_obj_iv_set_force(mrb, c, id_outer, mrb_obj_value(obj));
           }
         }
       }
@@ -434,7 +435,7 @@ mrb_iv_name_sym_p(mrb_state *mrb, mrb_sym iv_name)
   const char *s;
   mrb_int len;
 
-  s = mrb_sym2name_len(mrb, iv_name, &len);
+  s = mrb_sym_name_len(mrb, iv_name, &len);
   if (len < 2) return FALSE;
   if (s[0] != '@') return FALSE;
   if (ISDIGIT(s[1])) return FALSE;
@@ -445,7 +446,7 @@ MRB_API void
 mrb_iv_name_sym_check(mrb_state *mrb, mrb_sym iv_name)
 {
   if (!mrb_iv_name_sym_p(mrb, iv_name)) {
-    mrb_name_error(mrb, iv_name, "'%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name));
+    mrb_name_error(mrb, iv_name, "'%n' is not allowed as an instance variable name", iv_name);
   }
 }
 
@@ -482,10 +483,10 @@ inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
   else {
     mrb_str_cat_lit(mrb, str, ", ");
   }
-  s = mrb_sym2name_len(mrb, sym, &len);
+  s = mrb_sym_name_len(mrb, sym, &len);
   mrb_str_cat(mrb, str, s, len);
   mrb_str_cat_lit(mrb, str, "=");
-  if (mrb_type(v) == MRB_TT_OBJECT) {
+  if (mrb_object_p(v)) {
     ins = mrb_any_to_s(mrb, v);
   }
   else {
@@ -508,7 +509,7 @@ mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj)
     mrb_str_cat_lit(mrb, str, "-<");
     mrb_str_cat_cstr(mrb, str, cn);
     mrb_str_cat_lit(mrb, str, ":");
-    mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, obj));
+    mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, obj));
 
     iv_foreach(mrb, t, inspect_i, &str);
     mrb_str_cat_lit(mrb, str, ">");
@@ -524,6 +525,7 @@ mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym)
     iv_tbl *t = mrb_obj_ptr(obj)->iv;
     mrb_value val;
 
+    mrb_check_frozen(mrb, mrb_obj_ptr(obj));
     if (iv_del(mrb, t, sym, &val)) {
       return val;
     }
@@ -539,7 +541,7 @@ iv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
   mrb_int len;
 
   ary = *(mrb_value*)p;
-  s = mrb_sym2name_len(mrb, sym, &len);
+  s = mrb_sym_name_len(mrb, sym, &len);
   if (len > 1 && s[0] == '@' && s[1] != '@') {
     mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
   }
@@ -583,7 +585,7 @@ cv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
   mrb_int len;
 
   ary = *(mrb_value*)p;
-  s = mrb_sym2name_len(mrb, sym, &len);
+  s = mrb_sym_name_len(mrb, sym, &len);
   if (len > 2 && s[0] == '@' && s[1] == '@') {
     mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
   }
@@ -593,7 +595,7 @@ cv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
 /* 15.2.2.4.19 */
 /*
  *  call-seq:
- *     mod.class_variables   -> array
+ *     mod.class_variables(inherit=true)   -> array
  *
  *  Returns an array of the names of class variables in <i>mod</i>.
  *
@@ -611,11 +613,14 @@ mrb_mod_class_variables(mrb_state *mrb, mrb_value mod)
 {
   mrb_value ary;
   struct RClass *c;
+  mrb_bool inherit = TRUE;
 
+  mrb_get_args(mrb, "|b", &inherit);
   ary = mrb_ary_new(mrb);
   c = mrb_class_ptr(mod);
   while (c) {
     iv_foreach(mrb, c->iv, cv_i, &ary);
+    if (!inherit) break;
     c = c->super;
   }
   return ary;
@@ -652,8 +657,7 @@ mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym)
       if (given) return v;
     }
   }
-  mrb_name_error(mrb, sym, "uninitialized class variable %S in %S",
-                 mrb_sym2str(mrb, sym), mrb_obj_value(cls));
+  mrb_name_error(mrb, sym, "uninitialized class variable %n in %C", sym, cls);
   /* not reached */
   return mrb_nil_value();
 }
@@ -673,6 +677,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
     iv_tbl *t = c->iv;
 
     if (iv_get(mrb, t, sym, NULL)) {
+      mrb_check_frozen(mrb, c);
       iv_put(mrb, t, sym, v);
       mrb_write_barrier(mrb, (struct RBasic*)c);
       return;
@@ -700,6 +705,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
     c = cls;
   }
 
+  mrb_check_frozen(mrb, c);
   if (!c->iv) {
     c->iv = iv_new(mrb);
   }
@@ -737,7 +743,13 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
 {
   struct RClass *c;
 
-  c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
+  struct RProc *p = mrb->c->ci->proc;
+
+  for (;;) {
+    c = MRB_PROC_TARGET_CLASS(p);
+    if (c->tt != MRB_TT_SCLASS) break;
+    p = p->upper;
+  }
   return mrb_mod_cv_get(mrb, c, sym);
 }
 
@@ -745,8 +757,13 @@ void
 mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
 {
   struct RClass *c;
+  struct RProc *p = mrb->c->ci->proc;
 
-  c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
+  for (;;) {
+    c = MRB_PROC_TARGET_CLASS(p);
+    if (c->tt != MRB_TT_SCLASS) break;
+    p = p->upper;
+  }
   mrb_mod_cv_set(mrb, c, sym, v);
 }
 
@@ -877,9 +894,17 @@ const_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
   mrb_int len;
 
   ary = *(mrb_value*)p;
-  s = mrb_sym2name_len(mrb, sym, &len);
+  s = mrb_sym_name_len(mrb, sym, &len);
   if (len >= 1 && ISUPPER(s[0])) {
-    mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
+    mrb_int i, alen = RARRAY_LEN(ary);
+
+    for (i=0; i<alen; i++) {
+      if (mrb_symbol(RARRAY_PTR(ary)[i]) == sym)
+        break;
+    }
+    if (i==alen) {
+      mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
+    }
   }
   return 0;
 }
@@ -962,16 +987,8 @@ mrb_f_global_variables(mrb_state *mrb, mrb_value self)
 {
   iv_tbl *t = mrb->globals;
   mrb_value ary = mrb_ary_new(mrb);
-  size_t i;
-  char buf[3];
 
   iv_foreach(mrb, t, gv_i, &ary);
-  buf[0] = '$';
-  buf[2] = 0;
-  for (i = 1; i <= 9; ++i) {
-    buf[1] = (char)(i + '0');
-    mrb_ary_push(mrb, ary, mrb_symbol_value(mrb_intern(mrb, buf, 2)));
-  }
   return ary;
 }
 
@@ -1100,12 +1117,13 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c)
   mrb_str_cat_cstr(mrb, path, str);
   mrb_str_cat_cstr(mrb, path, "::");
 
-  str = mrb_sym2name_len(mrb, name, &len);
+  str = mrb_sym_name_len(mrb, name, &len);
   mrb_str_cat(mrb, path, str, len);
   if (RSTRING_PTR(path)[0] != '#') {
     iv_del(mrb, c->iv, mrb_intern_lit(mrb, "__outer__"), NULL);
     iv_put(mrb, c->iv, mrb_intern_lit(mrb, "__classname__"), path);
     mrb_field_write_barrier_value(mrb, (struct RBasic*)c, path);
+    path = mrb_str_dup(mrb, path);
   }
   return path;
 }
@@ -1115,7 +1133,9 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c)
 mrb_bool
 mrb_ident_p(const char *s, mrb_int len)
 {
-  for (mrb_int i = 0; i < len; i++) {
+  mrb_int i;
+
+  for (i = 0; i < len; i++) {
     if (!identchar(s[i])) return FALSE;
   }
   return TRUE;
index a381de2..f74be7e 100644 (file)
@@ -6,7 +6,9 @@
 
 #include <stddef.h>
 #include <stdarg.h>
+#ifndef MRB_WITHOUT_FLOAT
 #include <math.h>
+#endif
 #include <mruby.h>
 #include <mruby/array.h>
 #include <mruby/class.h>
@@ -150,7 +152,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize
     struct REnv *e = ci->env;
     mrb_value *st;
 
-    if (e && MRB_ENV_STACK_SHARED_P(e) &&
+    if (e && MRB_ENV_ONSTACK_P(e) &&
         (st = e->stack) && oldbase <= st && st < oldbase+oldsize) {
       ptrdiff_t off = e->stack - oldbase;
 
@@ -160,7 +162,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize
     if (ci->proc && MRB_PROC_ENV_P(ci->proc) && ci->env != MRB_PROC_ENV(ci->proc)) {
       e = MRB_PROC_ENV(ci->proc);
 
-      if (e && MRB_ENV_STACK_SHARED_P(e) &&
+      if (e && MRB_ENV_ONSTACK_P(e) &&
           (st = e->stack) && oldbase <= st && st < oldbase+oldsize) {
         ptrdiff_t off = e->stack - oldbase;
 
@@ -295,10 +297,10 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e)
 {
   if (e == NULL) return;
   else {
-    size_t len = (size_t)MRB_ENV_STACK_LEN(e);
+    size_t len = (size_t)MRB_ENV_LEN(e);
     mrb_value *p;
 
-    if (!MRB_ENV_STACK_SHARED_P(e)) return;
+    if (!MRB_ENV_ONSTACK_P(e)) return;
     if (e->cxt != mrb->c) return;
     if (e == mrb->c->cibase->env) return; /* for mirb */
     p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
@@ -306,7 +308,7 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e)
       stack_copy(p, e->stack, len);
     }
     e->stack = p;
-    MRB_ENV_UNSHARE_STACK(e);
+    MRB_ENV_CLOSE(e);
     mrb_write_barrier(mrb, (struct RBasic *)e);
   }
 }
@@ -322,6 +324,7 @@ cipop(mrb_state *mrb)
 }
 
 void mrb_exc_set(mrb_state *mrb, mrb_value exc);
+static mrb_value mrb_run(mrb_state *mrb, struct RProc* proc, mrb_value self);
 
 static void
 ecall(mrb_state *mrb)
@@ -333,10 +336,12 @@ ecall(mrb_state *mrb)
   struct REnv *env;
   ptrdiff_t cioff;
   int ai = mrb_gc_arena_save(mrb);
-  uint16_t i = --c->eidx;
+  uint16_t i;
   int nregs;
 
-  if (i<0) return;
+  if (c->eidx == 0) return;
+  i = --c->eidx;
+
   /* restrict total call depth of ecall() */
   if (++mrb->ecall_nest > MRB_ECALL_DEPTH_MAX) {
     mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
@@ -428,6 +433,7 @@ MRB_API mrb_value
 mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk)
 {
   mrb_value val;
+  int ai = mrb_gc_arena_save(mrb);
 
   if (!mrb->jmp) {
     struct mrb_jmpbuf c_jmp;
@@ -461,7 +467,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
       stack_init(mrb);
     }
     if (argc < 0) {
-      mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc));
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%i)", argc);
     }
     c = mrb_class(mrb, self);
     m = mrb_method_search_vm(mrb, &c, mid);
@@ -486,26 +492,25 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
     ci->argc = (int)argc;
     ci->target_class = c;
     mrb->c->stack = mrb->c->stack + n;
+    if (argc < 0) argc = 1;
     if (mrb->c->stbase <= argv && argv < mrb->c->stend) {
       voff = argv - mrb->c->stbase;
     }
-    if (MRB_METHOD_CFUNC_P(m)) {
-      mrb_stack_extend(mrb, argc + 2);
-    }
-    else if (argc >= CALL_MAXARGS) {
+    if (argc >= CALL_MAXARGS) {
       mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
 
-      mrb_stack_extend(mrb, 3);
       mrb->c->stack[1] = args;
       ci->argc = -1;
       argc = 1;
     }
-    else {
+    mrb_stack_extend(mrb, argc + 2);
+    if (MRB_METHOD_PROC_P(m)) {
       struct RProc *p = MRB_METHOD_PROC(m);
 
       ci->proc = p;
-      if (argc < 0) argc = 1;
-      mrb_stack_extend(mrb, p->body.irep->nregs + argc);
+      if (!MRB_PROC_CFUNC_P(p)) {
+        mrb_stack_extend(mrb, p->body.irep->nregs + argc);
+      }
     }
     if (voff >= 0) {
       argv = mrb->c->stbase + voff;
@@ -517,22 +522,17 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
     mrb->c->stack[argc+1] = blk;
 
     if (MRB_METHOD_CFUNC_P(m)) {
-      int ai = mrb_gc_arena_save(mrb);
-
       ci->acc = CI_ACC_DIRECT;
-      if (MRB_METHOD_PROC_P(m)) {
-        ci->proc = MRB_METHOD_PROC(m);
-      }
       val = MRB_METHOD_CFUNC(m)(mrb, self);
       mrb->c->stack = mrb->c->ci->stackent;
       cipop(mrb);
-      mrb_gc_arena_restore(mrb, ai);
     }
     else {
       ci->acc = CI_ACC_SKIP;
       val = mrb_run(mrb, MRB_METHOD_PROC(m), self);
     }
   }
+  mrb_gc_arena_restore(mrb, ai);
   mrb_gc_protect(mrb, val);
   return val;
 }
@@ -627,7 +627,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
     ci->argc--;
   }
   else {                     /* variable length arguments */
-    mrb_ary_shift(mrb, regs[0]);
+    regs[0] = mrb_ary_subseq(mrb, regs[0], 1, RARRAY_LEN(regs[0]) - 1);
   }
 
   if (MRB_METHOD_CFUNC_P(m)) {
@@ -651,8 +651,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
   }
   ci = mrb->c->ci;
   if (ci->acc == CI_ACC_DIRECT) {
-    ci->target_class = c;
-    return mrb_yield_cont(mrb, blk, self, 1, &self);
+    return mrb_yield_with_class(mrb, blk, 1, &self, self, c);
   }
   ci->target_class = c;
   p = mrb_proc_ptr(blk);
@@ -727,26 +726,11 @@ mrb_value
 mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
 {
   mrb_value a, b;
-  mrb_value cv;
-  struct RClass *c;
 
   if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
     mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented");
   }
-  switch (mrb_type(self)) {
-  case MRB_TT_SYMBOL:
-  case MRB_TT_FIXNUM:
-#ifndef MRB_WITHOUT_FLOAT
-  case MRB_TT_FLOAT:
-#endif
-    c = 0;
-    break;
-  default:
-    cv = mrb_singleton_class(mrb, self);
-    c = mrb_class_ptr(cv);
-    break;
-  }
-  return eval_under(mrb, self, b, c);
+  return eval_under(mrb, self, b, mrb_singleton_class_ptr(mrb, self));
 }
 
 MRB_API mrb_value
@@ -770,16 +754,25 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
   ci = cipush(mrb);
   ci->mid = mid;
   ci->proc = p;
-  ci->stackent = mrb->c->stack;
-  ci->argc = (int)argc;
   ci->target_class = c;
   ci->acc = CI_ACC_SKIP;
-  n = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs;
-  mrb->c->stack = mrb->c->stack + n;
+  ci->stackent = mrb->c->stack;
+  mrb->c->stack += n;
+  if (argc >= CALL_MAXARGS) {
+    ci->argc = -1;
+    n = 3;
+  }
+  else {
+    ci->argc = (int)argc;
+    n = argc + 2;
+  }
   mrb_stack_extend(mrb, n);
-
   mrb->c->stack[0] = self;
-  if (argc > 0) {
+  if (ci->argc < 0) {
+    mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
+    argc = 1;
+  }
+  else if (argc > 0) {
     stack_copy(mrb->c->stack+1, argv, argc);
   }
   mrb->c->stack[argc+1] = mrb_nil_value();
@@ -820,7 +813,7 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const
   if (mrb_nil_p(b)) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
   }
-  if (mrb_type(b) != MRB_TT_PROC) {
+  if (!mrb_proc_p(b)) {
     mrb_raise(mrb, E_TYPE_ERROR, "not a block");
   }
 
@@ -834,39 +827,14 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const
   return mrb_exec_irep(mrb, self, p);
 }
 
-mrb_value
-mrb_mod_s_nesting(mrb_state *mrb, mrb_value mod)
-{
-  struct RProc *proc;
-  mrb_value ary;
-  struct RClass *c = NULL;
-
-  mrb_get_args(mrb, "");
-  ary = mrb_ary_new(mrb);
-  proc = mrb->c->ci[-1].proc;   /* callee proc */
-  mrb_assert(!MRB_PROC_CFUNC_P(proc));
-  while (proc) {
-    if (MRB_PROC_SCOPE_P(proc)) {
-      struct RClass *c2 = MRB_PROC_TARGET_CLASS(proc);
-
-      if (c2 != c) {
-        c = c2;
-        mrb_ary_push(mrb, ary, mrb_obj_value(c));
-      }
-    }
-    proc = proc->upper;
-  }
-  return ary;
-}
-
 static struct RBreak*
 break_new(mrb_state *mrb, struct RProc *p, mrb_value val)
 {
   struct RBreak *brk;
 
   brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL);
-  brk->proc = p;
-  brk->val = val;
+  mrb_break_proc_set(brk, p);
+  mrb_break_value_set(brk, val);
 
   return brk;
 }
@@ -907,13 +875,11 @@ argnum_error(mrb_state *mrb, mrb_int num)
     }
   }
   if (mrb->c->ci->mid) {
-    str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)",
-                  mrb_sym2str(mrb, mrb->c->ci->mid),
-                  mrb_fixnum_value(argc), mrb_fixnum_value(num));
+    str = mrb_format(mrb, "'%n': wrong number of arguments (%i for %i)",
+                     mrb->c->ci->mid, argc, num);
   }
   else {
-    str = mrb_format(mrb, "wrong number of arguments (%S for %S)",
-                     mrb_fixnum_value(argc), mrb_fixnum_value(num));
+    str = mrb_format(mrb, "wrong number of arguments (%i for %i)", argc, num);
   }
   exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str);
   mrb_exc_set(mrb, exc);
@@ -1002,10 +968,10 @@ check_target_class(mrb_state *mrb)
 void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
 
 MRB_API mrb_value
-mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
+mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *pc)
 {
-  /* mrb_assert(mrb_proc_cfunc_p(proc)) */
-  mrb_code *pc0 = pc;
+  /* mrb_assert(MRB_PROC_CFUNC_P(proc)) */
+  const mrb_code *pc0 = pc;
   mrb_irep *irep = proc->body.irep;
   mrb_value *pool = irep->pool;
   mrb_sym *syms = irep->syms;
@@ -1092,6 +1058,11 @@ RETRY_TRY_BLOCK:
       NEXT;
     }
 
+    CASE(OP_LOADI16, BS) {
+      SET_INT_VALUE(regs[a], (mrb_int)(int16_t)b);
+      NEXT;
+    }
+
     CASE(OP_LOADSYM, BB) {
       SET_SYM_VALUE(regs[a], syms[b]);
       NEXT;
@@ -1129,13 +1100,13 @@ RETRY_TRY_BLOCK:
     }
 
     CASE(OP_GETSV, BB) {
-      mrb_value val = mrb_vm_special_get(mrb, b);
+      mrb_value val = mrb_vm_special_get(mrb, syms[b]);
       regs[a] = val;
       NEXT;
     }
 
     CASE(OP_SETSV, BB) {
-      mrb_vm_special_set(mrb, b, regs[a]);
+      mrb_vm_special_set(mrb, syms[b], regs[a]);
       NEXT;
     }
 
@@ -1198,7 +1169,7 @@ RETRY_TRY_BLOCK:
       mrb_value *regs_a = regs + a;
       struct REnv *e = uvenv(mrb, c);
 
-      if (e && b < MRB_ENV_STACK_LEN(e)) {
+      if (e && b < MRB_ENV_LEN(e)) {
         *regs_a = e->stack[b];
       }
       else {
@@ -1213,7 +1184,7 @@ RETRY_TRY_BLOCK:
       if (e) {
         mrb_value *regs_a = regs + a;
 
-        if (b < MRB_ENV_STACK_LEN(e)) {
+        if (b < MRB_ENV_LEN(e)) {
           e->stack[b] = *regs_a;
           mrb_write_barrier(mrb, (struct RBasic*)e);
         }
@@ -1418,7 +1389,7 @@ RETRY_TRY_BLOCK:
 
       recv = regs[a];
       blk = regs[bidx];
-      if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
+      if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) {
         blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
         /* The stack might have been reallocated during mrb_convert_type(),
            see #3622 */
@@ -1466,6 +1437,11 @@ RETRY_TRY_BLOCK:
           ci->proc = p;
           recv = p->body.func(mrb, recv);
         }
+        else if (MRB_METHOD_NOARG_P(m) &&
+                 (argc > 0 || (argc == -1 && RARRAY_LEN(regs[1]) != 0))) {
+          argnum_error(mrb, 0);
+          goto L_RAISE;
+        }
         else {
           recv = MRB_METHOD_FUNC(m)(mrb, recv);
         }
@@ -1473,7 +1449,7 @@ RETRY_TRY_BLOCK:
         mrb_gc_arena_shrink(mrb, ai);
         if (mrb->exc) goto L_RAISE;
         ci = mrb->c->ci;
-        if (mrb_type(blk) == MRB_TT_PROC) {
+        if (mrb_proc_p(blk)) {
           struct RProc *p = mrb_proc_ptr(blk);
           if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == ci[-1].env) {
             p->flags |= MRB_PROC_ORPHAN;
@@ -1521,14 +1497,7 @@ RETRY_TRY_BLOCK:
       ci->target_class = MRB_PROC_TARGET_CLASS(m);
       ci->proc = m;
       if (MRB_PROC_ENV_P(m)) {
-        mrb_sym mid;
-        struct REnv *e = MRB_PROC_ENV(m);
-
-        mid = e->mid;
-        if (mid) ci->mid = mid;
-        if (!e->stack) {
-          e->stack = mrb->c->stack;
-        }
+        ci->mid = MRB_PROC_ENV(m)->mid;
       }
 
       /* prepare stack */
@@ -1584,9 +1553,13 @@ RETRY_TRY_BLOCK:
       struct RClass *cls;
       mrb_callinfo *ci = mrb->c->ci;
       mrb_value recv, blk;
+      struct RProc *p = ci->proc;
       mrb_sym mid = ci->mid;
-      struct RClass* target_class = MRB_PROC_TARGET_CLASS(ci->proc);
+      struct RClass* target_class = MRB_PROC_TARGET_CLASS(p);
 
+      if (MRB_PROC_ENV_P(p) && p->e.env->mid && p->e.env->mid != mid) { /* alias support */
+        mid = p->e.env->mid;    /* restore old mid */
+      }
       mrb_assert(bidx < irep->nregs);
 
       if (mid == 0 || !target_class) {
@@ -1610,7 +1583,7 @@ RETRY_TRY_BLOCK:
         goto L_RAISE;
       }
       blk = regs[bidx];
-      if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
+      if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) {
         blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
         /* The stack or ci stack might have been reallocated during
            mrb_convert_type(), see #3622 and #3784 */
@@ -1720,7 +1693,7 @@ RETRY_TRY_BLOCK:
       else {
         struct REnv *e = uvenv(mrb, lv-1);
         if (!e) goto L_NOSUPER;
-        if (MRB_ENV_STACK_LEN(e) <= m1+r+m2+kd+1)
+        if (MRB_ENV_LEN(e) <= m1+r+m2+kd+1)
           goto L_NOSUPER;
         stack = e->stack + 1;
       }
@@ -1897,7 +1870,7 @@ RETRY_TRY_BLOCK:
       mrb_value kdict = regs[mrb->c->ci->argc];
 
       if (!mrb_hash_p(kdict) || !mrb_hash_key_p(mrb, kdict, k)) {
-        mrb_value str = mrb_format(mrb, "missing keyword: %S", k);
+        mrb_value str = mrb_format(mrb, "missing keyword: %v", k);
         mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str));
         goto L_RAISE;
       }
@@ -1924,7 +1897,7 @@ RETRY_TRY_BLOCK:
       if (mrb_hash_p(kdict) && !mrb_hash_empty_p(mrb, kdict)) {
         mrb_value keys = mrb_hash_keys(mrb, kdict);
         mrb_value key1 = RARRAY_PTR(keys)[0];
-        mrb_value str = mrb_format(mrb, "unknown keyword: %S", key1);
+        mrb_value str = mrb_format(mrb, "unknown keyword: %v", key1);
         mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str));
         goto L_RAISE;
       }
@@ -1961,7 +1934,7 @@ RETRY_TRY_BLOCK:
         else {
           blk = regs[ci->argc+1];
         }
-        if (mrb_type(blk) == MRB_TT_PROC) {
+        if (mrb_proc_p(blk)) {
           struct RProc *p = mrb_proc_ptr(blk);
 
           if (!MRB_PROC_STRICT_P(p) &&
@@ -2046,7 +2019,7 @@ RETRY_TRY_BLOCK:
             if (MRB_PROC_ENV_P(dst)) {
               struct REnv *e = MRB_PROC_ENV(dst);
 
-              if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt != mrb->c) {
+              if (!MRB_ENV_ONSTACK_P(e) || (e->cxt && e->cxt != mrb->c)) {
                 localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
                 goto L_RAISE;
               }
@@ -2101,7 +2074,7 @@ RETRY_TRY_BLOCK:
             mrb_exc_set(mrb, exc);
             goto L_RAISE;
           }
-          if (!MRB_PROC_ENV_P(proc) || !MRB_ENV_STACK_SHARED_P(MRB_PROC_ENV(proc))) {
+          if (!MRB_PROC_ENV_P(proc) || !MRB_ENV_ONSTACK_P(MRB_PROC_ENV(proc))) {
             goto L_BREAK_ERROR;
           }
           else {
@@ -2131,8 +2104,8 @@ RETRY_TRY_BLOCK:
           }
           if (FALSE) {
           L_BREAK:
-            v = ((struct RBreak*)mrb->exc)->val;
-            proc = ((struct RBreak*)mrb->exc)->proc;
+            v = mrb_break_value_get((struct RBreak*)mrb->exc);
+            proc = mrb_break_proc_get((struct RBreak*)mrb->exc);
             mrb->exc = NULL;
             ci = mrb->c->ci;
           }
@@ -2178,7 +2151,7 @@ RETRY_TRY_BLOCK:
         }
         pc = ci->pc;
         ci = mrb->c->ci;
-        DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid)));
+        DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid)));
         proc = mrb->c->ci->proc;
         irep = proc->body.irep;
         pool = irep->pool;
@@ -2201,8 +2174,8 @@ RETRY_TRY_BLOCK:
       if (lv == 0) stack = regs + 1;
       else {
         struct REnv *e = uvenv(mrb, lv-1);
-        if (!e || (!MRB_ENV_STACK_SHARED_P(e) && e->mid == 0) ||
-            MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) {
+        if (!e || (!MRB_ENV_ONSTACK_P(e) && e->mid == 0) ||
+            MRB_ENV_LEN(e) <= m1+r+m2+1) {
           localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
           goto L_RAISE;
         }
@@ -2217,184 +2190,67 @@ RETRY_TRY_BLOCK:
     }
 
 #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
-#define OP_MATH_BODY(op,v1,v2) do {\
-  v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\
-} while(0)
-
-    CASE(OP_ADD, B) {
-      /* need to check if op is overridden */
-      switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
-      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
-        {
-          mrb_int x, y, z;
-          mrb_value *regs_a = regs + a;
-
-          x = mrb_fixnum(regs_a[0]);
-          y = mrb_fixnum(regs_a[1]);
-          if (mrb_int_add_overflow(x, y, &z)) {
-#ifndef MRB_WITHOUT_FLOAT
-            SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y);
-            break;
-#endif
-          }
-          SET_INT_VALUE(regs[a], z);
-        }
-        break;
-#ifndef MRB_WITHOUT_FLOAT
-      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
-        {
-          mrb_int x = mrb_fixnum(regs[a]);
-          mrb_float y = mrb_float(regs[a+1]);
-          SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y);
-        }
-        break;
-      case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
-#ifdef MRB_WORD_BOXING
-        {
-          mrb_float x = mrb_float(regs[a]);
-          mrb_int y = mrb_fixnum(regs[a+1]);
-          SET_FLOAT_VALUE(mrb, regs[a], x + y);
-        }
-#else
-        OP_MATH_BODY(+,mrb_float,mrb_fixnum);
-#endif
-        break;
-      case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
-#ifdef MRB_WORD_BOXING
-        {
-          mrb_float x = mrb_float(regs[a]);
-          mrb_float y = mrb_float(regs[a+1]);
-          SET_FLOAT_VALUE(mrb, regs[a], x + y);
-        }
+#define OP_MATH(op_name)                                                    \
+  /* need to check if op is overridden */                                   \
+  switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {                  \
+    OP_MATH_CASE_FIXNUM(op_name);                                           \
+    OP_MATH_CASE_FLOAT(op_name, fixnum, float);                             \
+    OP_MATH_CASE_FLOAT(op_name, float,  fixnum);                            \
+    OP_MATH_CASE_FLOAT(op_name, float,  float);                             \
+    OP_MATH_CASE_STRING_##op_name();                                        \
+    default:                                                                \
+      c = 1;                                                                \
+      mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name));       \
+      goto L_SEND_SYM;                                                      \
+  }                                                                         \
+  NEXT;
+#define OP_MATH_CASE_FIXNUM(op_name)                                        \
+  case TYPES2(MRB_TT_FIXNUM, MRB_TT_FIXNUM):                                \
+    {                                                                       \
+      mrb_int x = mrb_fixnum(regs[a]), y = mrb_fixnum(regs[a+1]), z;        \
+      if (mrb_int_##op_name##_overflow(x, y, &z))                           \
+        OP_MATH_OVERFLOW_INT(op_name, x, y, z);                             \
+      else                                                                  \
+        SET_INT_VALUE(regs[a], z);                                          \
+    }                                                                       \
+    break
+#ifdef MRB_WITHOUT_FLOAT
+#define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0
+#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) SET_INT_VALUE(regs[a], z)
 #else
-        OP_MATH_BODY(+,mrb_float,mrb_float);
-#endif
-        break;
+#define OP_MATH_CASE_FLOAT(op_name, t1, t2)                                     \
+  case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2):                                \
+    {                                                                           \
+      mrb_float z = mrb_##t1(regs[a]) OP_MATH_OP_##op_name mrb_##t2(regs[a+1]); \
+      SET_FLOAT_VALUE(mrb, regs[a], z);                                         \
+    }                                                                           \
+    break
+#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) \
+  SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x OP_MATH_OP_##op_name (mrb_float)y)
 #endif
-      case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
-        regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
-        break;
-      default:
-        c = 1;
-        mid = mrb_intern_lit(mrb, "+");
-        goto L_SEND_SYM;
-      }
-      mrb_gc_arena_restore(mrb, ai);
-      NEXT;
+#define OP_MATH_CASE_STRING_add()                                           \
+  case TYPES2(MRB_TT_STRING, MRB_TT_STRING):                                \
+    regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);                        \
+    mrb_gc_arena_restore(mrb, ai);                                          \
+    break
+#define OP_MATH_CASE_STRING_sub() (void)0
+#define OP_MATH_CASE_STRING_mul() (void)0
+#define OP_MATH_OP_add +
+#define OP_MATH_OP_sub -
+#define OP_MATH_OP_mul *
+#define OP_MATH_TT_fixnum MRB_TT_FIXNUM
+#define OP_MATH_TT_float  MRB_TT_FLOAT
+
+    CASE(OP_ADD, B) {
+      OP_MATH(add);
     }
 
     CASE(OP_SUB, B) {
-      /* need to check if op is overridden */
-      switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
-      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
-        {
-          mrb_int x, y, z;
-
-          x = mrb_fixnum(regs[a]);
-          y = mrb_fixnum(regs[a+1]);
-          if (mrb_int_sub_overflow(x, y, &z)) {
-#ifndef MRB_WITHOUT_FLOAT
-            SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y);
-            break;
-#endif
-          }
-          SET_INT_VALUE(regs[a], z);
-        }
-        break;
-#ifndef MRB_WITHOUT_FLOAT
-      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
-        {
-          mrb_int x = mrb_fixnum(regs[a]);
-          mrb_float y = mrb_float(regs[a+1]);
-          SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y);
-        }
-        break;
-      case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
-#ifdef MRB_WORD_BOXING
-        {
-          mrb_float x = mrb_float(regs[a]);
-          mrb_int y = mrb_fixnum(regs[a+1]);
-          SET_FLOAT_VALUE(mrb, regs[a], x - y);
-        }
-#else
-        OP_MATH_BODY(-,mrb_float,mrb_fixnum);
-#endif
-        break;
-      case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
-#ifdef MRB_WORD_BOXING
-        {
-          mrb_float x = mrb_float(regs[a]);
-          mrb_float y = mrb_float(regs[a+1]);
-          SET_FLOAT_VALUE(mrb, regs[a], x - y);
-        }
-#else
-        OP_MATH_BODY(-,mrb_float,mrb_float);
-#endif
-        break;
-#endif
-      default:
-        c = 1;
-        mid = mrb_intern_lit(mrb, "-");
-        goto L_SEND_SYM;
-      }
-      NEXT;
+      OP_MATH(sub);
     }
 
     CASE(OP_MUL, B) {
-      /* need to check if op is overridden */
-      switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
-      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
-        {
-          mrb_int x, y, z;
-
-          x = mrb_fixnum(regs[a]);
-          y = mrb_fixnum(regs[a+1]);
-          if (mrb_int_mul_overflow(x, y, &z)) {
-#ifndef MRB_WITHOUT_FLOAT
-            SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y);
-            break;
-#endif
-          }
-          SET_INT_VALUE(regs[a], z);
-        }
-        break;
-#ifndef MRB_WITHOUT_FLOAT
-      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
-        {
-          mrb_int x = mrb_fixnum(regs[a]);
-          mrb_float y = mrb_float(regs[a+1]);
-          SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y);
-        }
-        break;
-      case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
-#ifdef MRB_WORD_BOXING
-        {
-          mrb_float x = mrb_float(regs[a]);
-          mrb_int y = mrb_fixnum(regs[a+1]);
-          SET_FLOAT_VALUE(mrb, regs[a], x * y);
-        }
-#else
-        OP_MATH_BODY(*,mrb_float,mrb_fixnum);
-#endif
-        break;
-      case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
-#ifdef MRB_WORD_BOXING
-        {
-          mrb_float x = mrb_float(regs[a]);
-          mrb_float y = mrb_float(regs[a+1]);
-          SET_FLOAT_VALUE(mrb, regs[a], x * y);
-        }
-#else
-        OP_MATH_BODY(*,mrb_float,mrb_float);
-#endif
-        break;
-#endif
-      default:
-        c = 1;
-        mid = mrb_intern_lit(mrb, "*");
-        goto L_SEND_SYM;
-      }
-      NEXT;
+      OP_MATH(mul);
     }
 
     CASE(OP_DIV, B) {
@@ -2449,84 +2305,46 @@ RETRY_TRY_BLOCK:
       NEXT;
     }
 
-    CASE(OP_ADDI, BB) {
-      /* need to check if + is overridden */
-      switch (mrb_type(regs[a])) {
-      case MRB_TT_FIXNUM:
-        {
-          mrb_int x = mrb_fixnum(regs[a]);
-          mrb_int y = (mrb_int)b;
-          mrb_int z;
-
-          if (mrb_int_add_overflow(x, y, &z)) {
-#ifndef MRB_WITHOUT_FLOAT
-            SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y);
-            break;
-#endif
-          }
-          SET_INT_VALUE(regs[a], z);
-        }
-        break;
-#ifndef MRB_WITHOUT_FLOAT
-      case MRB_TT_FLOAT:
-#ifdef MRB_WORD_BOXING
-        {
-          mrb_float x = mrb_float(regs[a]);
-          SET_FLOAT_VALUE(mrb, regs[a], x + b);
-        }
+#define OP_MATHI(op_name)                                                   \
+  /* need to check if op is overridden */                                   \
+  switch (mrb_type(regs[a])) {                                              \
+    OP_MATHI_CASE_FIXNUM(op_name);                                          \
+    OP_MATHI_CASE_FLOAT(op_name);                                           \
+    default:                                                                \
+      SET_INT_VALUE(regs[a+1], b);                                          \
+      c = 1;                                                                \
+      mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name));       \
+      goto L_SEND_SYM;                                                      \
+  }                                                                         \
+  NEXT;
+#define OP_MATHI_CASE_FIXNUM(op_name)                                       \
+  case MRB_TT_FIXNUM:                                                       \
+    {                                                                       \
+      mrb_int x = mrb_fixnum(regs[a]), y = (mrb_int)b, z;                   \
+      if (mrb_int_##op_name##_overflow(x, y, &z))                           \
+        OP_MATH_OVERFLOW_INT(op_name, x, y, z);                             \
+      else                                                                  \
+        SET_INT_VALUE(regs[a], z);                                          \
+    }                                                                       \
+    break
+#ifdef MRB_WITHOUT_FLOAT
+#define OP_MATHI_CASE_FLOAT(op_name) (void)0
 #else
-        mrb_float(regs[a]) += b;
-#endif
-        break;
+#define OP_MATHI_CASE_FLOAT(op_name)                                        \
+  case MRB_TT_FLOAT:                                                        \
+    {                                                                       \
+      mrb_float z = mrb_float(regs[a]) OP_MATH_OP_##op_name b;              \
+      SET_FLOAT_VALUE(mrb, regs[a], z);                                     \
+    }                                                                       \
+    break
 #endif
-      default:
-        SET_INT_VALUE(regs[a+1], b);
-        c = 1;
-        mid = mrb_intern_lit(mrb, "+");
-        goto L_SEND_SYM;
-      }
-      NEXT;
+
+    CASE(OP_ADDI, BB) {
+      OP_MATHI(add);
     }
 
     CASE(OP_SUBI, BB) {
-      mrb_value *regs_a = regs + a;
-
-      /* need to check if + is overridden */
-      switch (mrb_type(regs_a[0])) {
-      case MRB_TT_FIXNUM:
-        {
-          mrb_int x = mrb_fixnum(regs_a[0]);
-          mrb_int y = (mrb_int)b;
-          mrb_int z;
-
-          if (mrb_int_sub_overflow(x, y, &z)) {
-#ifndef MRB_WITHOUT_FLOAT
-            SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y);
-            break;
-#endif
-          }
-          SET_INT_VALUE(regs_a[0], z);
-        }
-        break;
-#ifndef MRB_WITHOUT_FLOAT
-      case MRB_TT_FLOAT:
-#ifdef MRB_WORD_BOXING
-        {
-          mrb_float x = mrb_float(regs[a]);
-          SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)b);
-        }
-#else
-        mrb_float(regs_a[0]) -= b;
-#endif
-        break;
-#endif
-      default:
-        SET_INT_VALUE(regs_a[1], b);
-        c = 1;
-        mid = mrb_intern_lit(mrb, "-");
-        goto L_SEND_SYM;
-      }
-      NEXT;
+      OP_MATHI(sub);
     }
 
 #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))
@@ -2627,7 +2445,12 @@ RETRY_TRY_BLOCK:
 
     CASE(OP_ARYCAT, B) {
       mrb_value splat = mrb_ary_splat(mrb, regs[a+1]);
-      mrb_ary_concat(mrb, regs[a], splat);
+      if (mrb_nil_p(regs[a])) {
+        regs[a] = splat;
+      }
+      else {
+        mrb_ary_concat(mrb, regs[a], splat);
+      }
       mrb_gc_arena_restore(mrb, ai);
       NEXT;
     }
@@ -2997,7 +2820,7 @@ RETRY_TRY_BLOCK:
   MRB_END_EXC(&c_jmp);
 }
 
-MRB_API mrb_value
+static mrb_value
 mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
 {
   if (mrb->c->ci->argc < 0) {
@@ -3018,14 +2841,15 @@ mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int sta
     return mrb_vm_run(mrb, proc, self, stack_keep);
   }
   if (mrb->c->ci == mrb->c->cibase) {
+    mrb->c->ci->env = NULL;
     return mrb_vm_run(mrb, proc, self, stack_keep);
   }
   ci = cipush(mrb);
+  ci->stackent = mrb->c->stack;
   ci->mid = 0;
   ci->acc = CI_ACC_SKIP;
   ci->target_class = mrb->object_class;
   v = mrb_vm_run(mrb, proc, self, stack_keep);
-  cipop(mrb);
 
   return v;
 }
diff --git a/third-party/mruby/tasks/doc.rake b/third-party/mruby/tasks/doc.rake
new file mode 100644 (file)
index 0000000..11b76bb
--- /dev/null
@@ -0,0 +1,48 @@
+desc 'generate document'
+task :doc => [:api_doc, :capi_doc] do
+
+end
+
+desc 'generate yard docs'
+task :api_doc do
+  begin
+    sh "mrbdoc"
+  rescue
+    puts "ERROR: To generate yard documentation, you should install yard-mruby gem."
+    puts "  $ gem install yard-mruby yard-coderay"
+  end
+end
+
+desc 'generate doxygen docs'
+task :capi_doc do
+  begin
+    sh "doxygen Doxyfile"
+  rescue
+    puts "ERROR: To generate C API documents, you need Doxygen."
+    puts "  $ sudo apt-get install doxygen"
+  end
+end
+
+desc 'clean all built docs'
+task :clean_api_doc do
+  rm_rf 'doc/api'
+end
+
+desc 'clean all built docs'
+task :clean_capi_doc do
+  rm_rf 'doc/capi'
+end
+
+desc 'clean all built docs'
+task :clean_doc => [:clean_api_doc, :clean_capi_doc] do
+end
+
+desc 'clean all built docs'
+task :view_api => [:api_doc] do
+  sh 'xdg-open doc/api/index.html'
+end
+
+desc 'clean all built docs'
+task :view_capi => [:capi_doc] do
+  sh 'xdg-open doc/capi/html/index.html'
+end
index 4711723..377b1cc 100644 (file)
@@ -63,28 +63,25 @@ task :gitlab_config do
   configs = []
   [true, false].each do |mode_32|
     ['', 'MRB_USE_FLOAT'].each do |float_conf|
-      ['', 'MRB_INT16', 'MRB_INT64'].each do |int_conf|
-        ['', 'MRB_NAN_BOXING', 'MRB_WORD_BOXING'].each do |boxing_conf|
-          ['', 'MRB_UTF8_STRING'].each do |utf8_conf|
-            next if (float_conf == 'MRB_USE_FLOAT') && (boxing_conf == 'MRB_NAN_BOXING')
-            next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_NAN_BOXING')
-            next if (int_conf == 'MRB_INT16') && (boxing_conf == 'MRB_WORD_BOXING')
-            next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_WORD_BOXING') && mode_32
-            env = [float_conf, int_conf, boxing_conf, utf8_conf].map do |conf|
-              conf == '' ? nil : "-D#{conf}=1"
-            end.compact.join(' ')
-            bit = mode_32 ? '-m32 ' : ''
-            _info = ''
-            _info += mode_32 ? '32bit ' : '64bit '
-            _info += float_conf['USE'] ? 'float ' : ''
-            _info += int_conf['16'] ? 'int16 ' : ''
-            _info += int_conf['64'] ? 'int64 ' : ''
-            _info += boxing_conf['NAN'] ? 'nan ' : ''
-            _info += boxing_conf['word'] ? 'word ' : ''
-            _info += utf8_conf['UTF8'] ? 'utf8 ' : ''
-            _info = _info.gsub(/ +/, ' ').strip.tr(' ', '_')
-            configs << { '_info' => _info, 'CFLAGS' => "#{bit}#{env}", 'LDFLAGS' => bit.strip.to_s }
-          end
+      ['', 'MRB_NAN_BOXING', 'MRB_WORD_BOXING'].each do |boxing_conf|
+        ['', 'MRB_UTF8_STRING'].each do |utf8_conf|
+          next if (float_conf == 'MRB_USE_FLOAT') && (boxing_conf == 'MRB_NAN_BOXING')
+          next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_NAN_BOXING')
+          next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_WORD_BOXING') && mode_32
+          env = [float_conf, int_conf, boxing_conf, utf8_conf].map do |conf|
+            conf == '' ? nil : "-D#{conf}=1"
+          end.compact.join(' ')
+          bit = mode_32 ? '-m32 ' : ''
+          _info = ''
+          _info += mode_32 ? '32bit ' : '64bit '
+          _info += float_conf['USE'] ? 'float ' : ''
+          _info += int_conf['16'] ? 'int16 ' : ''
+          _info += int_conf['64'] ? 'int64 ' : ''
+          _info += boxing_conf['NAN'] ? 'nan ' : ''
+          _info += boxing_conf['WORD'] ? 'word ' : ''
+          _info += utf8_conf['UTF8'] ? 'utf8 ' : ''
+          _info = _info.gsub(/ +/, ' ').strip.tr(' ', '_')
+          configs << { '_info' => _info, 'CFLAGS' => "#{bit}#{env}", 'LDFLAGS' => bit.strip.to_s }
         end
       end
     end
@@ -110,7 +107,7 @@ task :gitlab_config do
         'stage' => 'test',
         'image' => ci_docker_tag(compiler),
         'variables' => hash,
-        'script' => 'env; ./minirake --verbose all test'
+        'script' => 'env; rake --verbose all test'
       }
     end
   end
index ab5a15b..17f8534 100644 (file)
@@ -4,7 +4,7 @@ MRuby.each_target do
   end
 
   file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libmruby_static] do |t|
-    FileUtils.mkdir_p File.dirname t.name
+    mkdir_p File.dirname t.name
     open(t.name, 'w') do |f|
       f.puts "MRUBY_CFLAGS = #{cc.all_flags}"
 
index fb76856..c814a16 100644 (file)
@@ -7,8 +7,8 @@ MRuby.each_target do
     # loader all gems
     self.libmruby_objs << objfile("#{build_dir}/mrbgems/gem_init")
     file objfile("#{build_dir}/mrbgems/gem_init") => ["#{build_dir}/mrbgems/gem_init.c", "#{build_dir}/LEGAL"]
-    file "#{build_dir}/mrbgems/gem_init.c" => [MRUBY_CONFIG, __FILE__] do |t|
-      FileUtils.mkdir_p "#{build_dir}/mrbgems"
+    file "#{build_dir}/mrbgems/gem_init.c" => [MRUBY_CONFIG, __FILE__, *Dir.glob("#{build_dir}/mrbgems/mruby-*/*.c")] do |t|
+      mkdir_p "#{build_dir}/mrbgems"
       open(t.name, 'w') do |f|
         gem_func_gems = gems.select { |g| g.generate_functions }
         gem_func_decls = gem_func_gems.each_with_object('') do |g, s|
@@ -53,7 +53,7 @@ MRuby.each_target do
 
   # legal documents
   file "#{build_dir}/LEGAL" => [MRUBY_CONFIG, __FILE__] do |t|
-    FileUtils.mkdir_p File.dirname t.name
+    mkdir_p File.dirname t.name
     open(t.name, 'w+') do |f|
      f.puts <<LEGAL
 Copyright (c) #{Time.now.year} mruby developers
index c7df9ef..2368b93 100644 (file)
@@ -10,6 +10,7 @@ class MRuby::Toolchain::Android
     ~/Android/Sdk/ndk-bundle
     %LOCALAPPDATA%/Android/android-sdk/ndk-bundle
     %LOCALAPPDATA%/Android/android-ndk
+    %LOCALAPPDATA%/Android/Sdk/ndk/*
     ~/Library/Android/sdk/ndk-bundle
     ~/Library/Android/ndk
   }
@@ -40,6 +41,19 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
     end
   end
 
+  class SysrootNotReady < StandardError
+    def message
+      <<-EOM
+Couldn't find standard header files
+Please Move/Copy important file inside
+  <NDK_HOME>/sysroot/usr/include/
+to
+  <NDK_HOME>/platforms/<ANDROID_VERSION>/<ARCH>/usr/include/
+Higher NDK version will be use.
+      EOM
+    end
+  end
+
   attr_reader :params
 
   def initialize(params)
@@ -67,13 +81,32 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
   end
 
   def home_path
-    @home_path ||= Pathname(
+    @home_path ||= Pathname.new(
       params[:ndk_home] ||
       ENV['ANDROID_NDK_HOME'] ||
       DEFAULT_NDK_HOMES.find { |path|
         path.gsub! '%LOCALAPPDATA%', ENV['LOCALAPPDATA'] || '%LOCALAPPDATA%'
         path.gsub! '\\', '/'
         path.gsub! '~', Dir.home || '~'
+        path.gsub!('*') do
+          next nil unless path[-1] == "*"
+          dirs = Dir.glob(path).collect do |d|
+            m = d.match(/(\d+)\.(\d+)\.(\d+)$/)
+            m ? [m[1], m[2], m[3]].collect { |v| v.to_i } : nil
+          end
+          dirs.compact!
+          dirs.sort! do |before, after|
+            f = 0
+            if (f = (after.first <=> before.first)) != 0
+              next f
+            elsif (f = (after[1] <=> before[1])) != 0
+              next f
+            else
+              next after.last <=> before.last
+            end
+          end
+          dirs.empty? ? nil.to_s : dirs.first.join(".")
+        end
         File.directory?(path)
       } || raise(AndroidNDKHomeNotFound)
     )
@@ -124,7 +157,7 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
         path = home_path.join('toolchains', 'llvm' , 'prebuilt', 'windows*')
         Dir.glob(path.to_s){ |item|
           next if File.file?(item)
-          path = Pathname(item)
+          path = Pathname.new(item)
           break
         }
         path.basename
@@ -146,7 +179,8 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
   end
 
   def sysroot
-    @sysroot ||= home_path.join('platforms', platform,
+    return @sysroot if @sysroot
+    sysroot_path = home_path.join('platforms', platform,
         case arch
         when /armeabi/    then 'arch-arm'
         when /arm64-v8a/  then 'arch-arm64'
@@ -156,6 +190,11 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
         when /mips/       then 'arch-mips'
         end
       ).to_s
+    if Dir.exist?(File.join(sysroot_path, "usr", "include"))
+      return @sysroot = sysroot_path
+    else
+      raise(SysrootNotReady)
+    end
   end
 
   def platform
@@ -259,6 +298,12 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
   def cflags
     flags = []
 
+    case RUBY_PLATFORM
+    when /mswin|mingw|win32/
+      # Build for Android dont need window flag
+      flags += %W(-U_WIN32 -U_WIN64)
+    end
+
     flags += %W(-MMD -MP -D__android__ -DANDROID --sysroot="#{sysroot}")
     flags += ctarget
     case toolchain
index 2832dad..543cb73 100644 (file)
@@ -1,9 +1,8 @@
 MRuby::Toolchain.new(:clang) do |conf, _params|
-  toolchain :gcc
+  toolchain :gcc, default_command: 'clang'
 
   [conf.cc, conf.objc, conf.asm].each do |cc|
-    cc.command = ENV['CC'] || 'clang'
+    cc.flags << '-Wzero-length-array' unless ENV['CFLAGS']
   end
-  conf.cxx.command = ENV['CXX'] || 'clang++'
-  conf.linker.command = ENV['LD'] || ENV['CXX'] || ENV['CC'] || 'clang'
+  conf.cxx.flags << '-Wzero-length-array' unless ENV['CXXFLAGS'] || ENV['CFLAGS']
 end
index 663fef9..810f23b 100644 (file)
@@ -1,32 +1,33 @@
-MRuby::Toolchain.new(:gcc) do |conf, _params|
-  [conf.cc, conf.objc, conf.asm].each do |cc|
-    cc.command = ENV['CC'] || 'gcc'
-    cc.flags = [ENV['CFLAGS'] || %w(-g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings -Wundef)]
-    cc.option_include_path = '-I%s'
-    cc.option_define = '-D%s'
-    cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
-    cc.cxx_compile_flag = '-x c++ -std=c++03'
-    cc.cxx_exception_flag = '-fexceptions'
-  end
+MRuby::Toolchain.new(:gcc) do |conf, params|
+  default_command = params[:default_command] || 'gcc'
+  compiler_flags = %w(-g -O3 -Wall -Wundef)
+  c_mandatory_flags = %w(-std=gnu99)
+  cxx_invalid_flags = %w(-Wdeclaration-after-statement -Werror-implicit-function-declaration)
 
-  [conf.cxx].each do |cxx|
-    cxx.command = ENV['CXX'] || 'g++'
-    cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(-g -O3 -Wall -Werror-implicit-function-declaration -Wundef)]
-    cxx.option_include_path = '-I%s'
-    cxx.option_define = '-D%s'
-    cxx.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
-    cxx.cxx_compile_flag = '-x c++ -std=c++03'
-    cxx.cxx_exception_flag = '-fexceptions'
+  [conf.cc, conf.objc, conf.asm, conf.cxx].each do |compiler|
+    if compiler == conf.cxx
+      compiler.command = ENV['CXX'] || default_command.sub(/cc|$/, '++')
+      compiler.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || compiler_flags]
+    else
+      compiler.command = ENV['CC'] || default_command
+      compiler.flags = [c_mandatory_flags, ENV['CFLAGS'] || [compiler_flags, cxx_invalid_flags, %w(-Wwrite-strings)]]
+    end
+    compiler.option_include_path = %q[-I"%s"]
+    compiler.option_define = '-D%s'
+    compiler.compile_options = %q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"]
+    compiler.cxx_compile_flag = '-x c++ -std=gnu++03'
+    compiler.cxx_exception_flag = '-fexceptions'
+    compiler.cxx_invalid_flags = c_mandatory_flags + cxx_invalid_flags
   end
 
   conf.linker do |linker|
-    linker.command = ENV['LD'] || ENV['CXX'] || ENV['CC'] || 'gcc'
+    linker.command = ENV['LD'] || ENV['CXX'] || ENV['CC'] || default_command
     linker.flags = [ENV['LDFLAGS'] || %w()]
     linker.libraries = %w(m)
     linker.library_paths = []
     linker.option_library = '-l%s'
     linker.option_library_path = '-L%s'
-    linker.link_options = '%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
+    linker.link_options = '%{flags} -o "%{outfile}" %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
   end
 
   [[conf.cc, 'c'], [conf.cxx, 'c++']].each do |cc, lang|
index aeb6dbc..c376d96 100644 (file)
@@ -5,18 +5,18 @@ MRuby::Toolchain.new(:openwrt) do |conf|
     cc.command = ENV['TARGET_CC']
     cc.flags = ENV['TARGET_CFLAGS']
     cc.include_paths = ["#{MRUBY_ROOT}/include"]
-    cc.option_include_path = '-I%s'
+    cc.option_include_path = %q[-I"%s"]
     cc.option_define = '-D%s'
-    cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+    cc.compile_options = %q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"]
   end
 
   [conf.cxx].each do |cxx|
     cxx.command = ENV['TARGET_CXX']
     cxx.flags = ENV['TARGET_CXXFLAGS']
     cxx.include_paths = ["#{MRUBY_ROOT}/include"]
-    cxx.option_include_path = '-I%s'
+    cxx.option_include_path = %q[-I"%s"]
     cxx.option_define = '-D%s'
-    cxx.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+    cxx.compile_options = %q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"]
    end
 
   conf.linker do |linker|
@@ -26,11 +26,11 @@ MRuby::Toolchain.new(:openwrt) do |conf|
     linker.library_paths = []
     linker.option_library = '-l%s'
     linker.option_library_path = '-L%s'
-    linker.link_options = '%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
+    linker.link_options = '%{flags} -o "%{outfile}" %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
   end
 
   conf.archiver do |archiver|
     archiver.command = ENV['TARGET_AR']
-    archiver.archive_options = 'rs %{outfile} %{objs}'
+    archiver.archive_options = 'rs "%{outfile}" %{objs}'
   end
 end
index 6275059..5094495 100644 (file)
@@ -4,9 +4,9 @@ MRuby::Toolchain.new(:visualcpp) do |conf, _params|
     # C4013: implicit function declaration
     cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /we4013 /Zi /MD /O2 /D_CRT_SECURE_NO_WARNINGS)]
     cc.defines = %w(MRB_STACK_EXTEND_DOUBLING)
-    cc.option_include_path = '/I%s'
+    cc.option_include_path = %q[/I"%s"]
     cc.option_define = '/D%s'
-    cc.compile_options = "%{flags} /Fo%{outfile} %{infile}"
+    cc.compile_options = %Q[%{flags} /Fo"%{outfile}" "%{infile}"]
     cc.cxx_compile_flag = '/TP'
     cc.cxx_exception_flag = '/EHs'
   end
@@ -15,9 +15,9 @@ MRuby::Toolchain.new(:visualcpp) do |conf, _params|
     cxx.command = ENV['CXX'] || 'cl.exe'
     cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(/c /nologo /W3 /Zi /MD /O2 /EHs /D_CRT_SECURE_NO_WARNINGS)]
     cxx.defines = %w(MRB_STACK_EXTEND_DOUBLING)
-    cxx.option_include_path = '/I%s'
+    cxx.option_include_path = %q[/I"%s"]
     cxx.option_define = '/D%s'
-    cxx.compile_options = "%{flags} /Fo%{outfile} %{infile}"
+    cxx.compile_options = %Q[%{flags} /Fo"%{outfile}" "%{infile}"]
     cxx.cxx_compile_flag = '/TP'
     cxx.cxx_exception_flag = '/EHs'
   end
@@ -29,22 +29,22 @@ MRuby::Toolchain.new(:visualcpp) do |conf, _params|
     linker.library_paths = %w()
     linker.option_library = '%s.lib'
     linker.option_library_path = '/LIBPATH:%s'
-    linker.link_options = "%{flags} /OUT:%{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}"
+    linker.link_options = %Q[%{flags} /OUT:"%{outfile}" %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}]
   end
 
   conf.archiver do |archiver|
     archiver.command = ENV['AR'] || 'lib.exe'
-    archiver.archive_options = '/nologo /OUT:%{outfile} %{objs}'
+    archiver.archive_options = '/nologo /OUT:"%{outfile}" %{objs}'
   end
 
   conf.yacc do |yacc|
     yacc.command = ENV['YACC'] || 'bison.exe'
-    yacc.compile_options = '-o %{outfile} %{infile}'
+    yacc.compile_options = %q[-o "%{outfile}" "%{infile}"]
   end
 
   conf.gperf do |gperf|
     gperf.command = 'gperf.exe'
-    gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
+    gperf.compile_options = %q[-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" "%{infile}" > "%{outfile}"]
   end
 
   conf.exts do |exts|
@@ -54,16 +54,4 @@ MRuby::Toolchain.new(:visualcpp) do |conf, _params|
   end
 
   conf.file_separator = '\\'
-
-  # Unreliable detection and will result in invalid encoding errors for localized versions of Visual C++
-  # if require 'open3'
-  #   Open3.popen3 conf.cc.command do |_, _, e, _|
-  #     if /Version (\d{2})\.\d{2}\.\d{5}/ =~ e.gets && $1.to_i <= 17
-  #       m = "# VS2010/2012 support will be dropped after the next release! #"
-  #       h = "#" * m.length
-  #       puts h, m, h
-  #     end
-  #   end
-  # end
-
 end
index c57b04c..73382fb 100644 (file)
@@ -1,17 +1,53 @@
+$undefined = Object.new
 $ok_test = 0
 $ko_test = 0
 $kill_test = 0
+$warning_test = 0
 $skip_test = 0
 $asserts  = []
 $test_start = Time.now if Object.const_defined?(:Time)
 
+# For bintest on Ruby
 unless RUBY_ENGINE == "mruby"
-  # For bintest on Ruby
   def t_print(*args)
     print(*args)
     $stdout.flush
     nil
   end
+
+  def _str_match?(pattern, str)
+    File.fnmatch?(pattern, str, File::FNM_EXTGLOB|File::FNM_DOTMATCH)
+  end
+end
+
+class Array
+  def _assertion_join
+    join("-")
+  end
+end
+
+class String
+  def _assertion_indent(indent)
+    indent = indent.to_s
+    off = 0
+    str = self
+    while nl = index("\n", off)
+      nl += 1
+      nl += 1 while slice(nl) == "\n"
+      break if nl >= size
+      str = indent.dup if off == 0
+      str += slice(off, nl - off) + indent
+      off = nl
+    end
+
+    if off == 0
+      str = indent + self
+    else
+      str += slice(off..-1)
+    end
+
+    str
+  end
 end
 
 ##
@@ -20,15 +56,17 @@ def assertion_string(err, str, iso=nil, e=nil, bt=nil)
   msg = "#{err}#{str}"
   msg += " [#{iso}]" if iso && !iso.empty?
   msg += " => #{e}" if e && !e.to_s.empty?
-  msg += " (#{GEMNAME == 'mruby-test' ? 'core' : "mrbgems: #{GEMNAME}"})"
-  if $mrbtest_assert && $mrbtest_assert.size > 0
+  if Object.const_defined?(:GEMNAME)
+    msg += " (#{GEMNAME == 'mruby-test' ? 'core' : "mrbgems: #{GEMNAME}"})"
+  end
+  if $mrbtest_assert
     $mrbtest_assert.each do |idx, assert_msg, diff|
       msg += "\n - Assertion[#{idx}]"
       msg += " #{assert_msg}." if assert_msg && !assert_msg.empty?
       msg += "\n#{diff}" if diff && !diff.empty?
     end
   end
-  msg += "\nbacktrace:\n\t#{bt.join("\n\t")}" if bt
+  msg += "\nbacktrace:\n        #{bt.join("\n        ")}" if bt && !bt.empty?
   msg
 end
 
@@ -40,16 +78,42 @@ end
 # iso : The ISO reference code of the feature
 #       which will be tested by this
 #       assertion
-def assert(str = 'Assertion failed', iso = '')
+def assert(str = 'assert', iso = '')
   t_print(str, (iso != '' ? " [#{iso}]" : ''), ' : ') if $mrbtest_verbose
   begin
+    $mrbtest_child_noassert ||= [0]
+    $mrbtest_child_noassert << 0
+    parent_asserts = $asserts
+    $asserts = []
+    parent_mrbtest_assert = $mrbtest_assert
     $mrbtest_assert = []
-    $mrbtest_assert_idx = 0
+
+    if $mrbtest_assert_idx && !$mrbtest_assert_idx.empty?
+      $mrbtest_assert_idx[-1] += 1
+      $mrbtest_assert_idx << 0
+    else
+      $mrbtest_assert_idx = [0]
+      class << $mrbtest_assert_idx
+        alias to_s _assertion_join
+      end
+    end
+
     yield
-    if($mrbtest_assert.size > 0)
-      $asserts.push(assertion_string('Fail: ', str, iso))
-      $ko_test += 1
-      t_print('F')
+    if $mrbtest_assert.size > 0
+      if $mrbtest_assert.size == $mrbtest_child_noassert[-1]
+        $asserts.push(assertion_string('Skip: ', str, iso))
+        $mrbtest_child_noassert[-2] += 1
+        $skip_test += 1
+        t_print('?')
+      else
+        $asserts.push(assertion_string('Fail: ', str, iso))
+        $ko_test += 1
+        t_print('F')
+      end
+    elsif $mrbtest_assert_idx[-1] == 0
+      $asserts.push(assertion_string('Warn: ', str, iso, 'no assertion'))
+      $warning_test += 1
+      t_print('W')
     else
       $ok_test += 1
       t_print('.')
@@ -57,14 +121,32 @@ def assert(str = 'Assertion failed', iso = '')
   rescue MRubyTestSkip => e
     $asserts.push(assertion_string('Skip: ', str, iso, e))
     $skip_test += 1
+    $mrbtest_child_noassert[-2] += 1
     t_print('?')
   rescue Exception => e
-    bt = e.backtrace if $mrbtest_verbose
-    $asserts.push(assertion_string("#{e.class}: ", str, iso, e, bt))
+    $asserts.push(assertion_string("#{e.class}: ", str, iso, e, e.backtrace))
     $kill_test += 1
     t_print('X')
   ensure
-    $mrbtest_assert = nil
+    if $mrbtest_assert_idx.size > 1
+      $asserts.each do |mesg|
+        idx = $mrbtest_assert_idx[0..-2]._assertion_join
+        mesg = mesg._assertion_indent("    ")
+
+        # Give `mesg` as a `diff` argument to avoid adding extra periods.
+        parent_mrbtest_assert << [idx, nil, mesg]
+      end
+    else
+      parent_asserts.concat $asserts
+    end
+    $asserts = parent_asserts
+
+    $mrbtest_assert = parent_mrbtest_assert
+    $mrbtest_assert_idx.pop
+    $mrbtest_assert_idx = nil if $mrbtest_assert_idx.empty?
+    $mrbtest_child_noassert.pop
+
+    nil
   end
   t_print("\n") if $mrbtest_verbose
 end
@@ -75,11 +157,11 @@ def assertion_diff(exp, act)
 end
 
 def assert_true(obj, msg = nil, diff = nil)
-  if $mrbtest_assert
-    $mrbtest_assert_idx += 1
+  if $mrbtest_assert_idx && $mrbtest_assert_idx.size > 0
+    $mrbtest_assert_idx[-1] += 1
     unless obj == true
       diff ||= "    Expected #{obj.inspect} to be true."
-      $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
+      $mrbtest_assert.push([$mrbtest_assert_idx.to_s, msg, diff])
     end
   end
   obj
@@ -127,6 +209,13 @@ def assert_nil(obj, msg = nil)
   assert_true(ret, msg, diff)
 end
 
+def assert_not_nil(obj, msg = nil)
+  if ret = obj.nil?
+    diff = "    Expected #{obj.inspect} to not be nil."
+  end
+  assert_false(ret, msg, diff)
+end
+
 def assert_include(*args); _assert_include(true, *args) end
 def assert_not_include(*args); _assert_include(false, *args) end
 def _assert_include(affirmed, collection, obj, msg = nil)
@@ -136,6 +225,55 @@ def _assert_include(affirmed, collection, obj, msg = nil)
   assert_true(ret, msg, diff)
 end
 
+def assert_predicate(*args); _assert_predicate(true, *args) end
+def assert_not_predicate(*args); _assert_predicate(false, *args) end
+def _assert_predicate(affirmed, obj, op, msg = nil)
+  unless ret = obj.__send__(op) == affirmed
+    diff = "    Expected #{obj.inspect} to #{'not ' unless affirmed}be #{op}."
+  end
+  assert_true(ret, msg, diff)
+end
+
+def assert_operator(*args); _assert_operator(true, *args) end
+def assert_not_operator(*args); _assert_operator(false, *args) end
+def _assert_operator(affirmed, obj1, op, obj2 = $undefined, msg = nil)
+  return _assert_predicate(affirmed, obj1, op, msg) if $undefined.equal?(obj2)
+  unless ret = obj1.__send__(op, obj2) == affirmed
+    diff = "    Expected #{obj1.inspect} to #{'not ' unless affirmed}be #{op} #{obj2.inspect}."
+  end
+  assert_true(ret, msg, diff)
+end
+
+##
+# Fail unless +str+ matches against +pattern+.
+#
+# +pattern+ is interpreted as pattern for File.fnmatch?. It may contain the
+# following metacharacters:
+#
+# <code>*</code> ::
+#   Matches any string.
+#
+# <code>?</code> ::
+#   Matches any one character.
+#
+# <code>[_SET_]</code>, <code>[^_SET_]</code> (<code>[!_SET_]</code>) ::
+#   Matches any one character in _SET_.  Behaves like character sets in
+#   Regexp, including set negation (<code>[^a-z]</code>).
+#
+# <code>{_A_,_B_}</code> ::
+#   Matches pattern _A_ or pattern _B_.
+#
+# <code> \ </code> ::
+#   Escapes the next character.
+def assert_match(*args); _assert_match(true, *args) end
+def assert_not_match(*args); _assert_match(false, *args) end
+def _assert_match(affirmed, pattern, str, msg = nil)
+  unless ret = _str_match?(pattern, str) == affirmed
+    diff = "    Expected #{pattern.inspect} to #{'not ' unless affirmed}match #{str.inspect}."
+  end
+  assert_true(ret, msg, diff)
+end
+
 ##
 # Fails unless +obj+ is a kind of +cls+.
 def assert_kind_of(cls, obj, msg = nil)
@@ -149,11 +287,11 @@ end
 # Fails unless +exp+ is equal to +act+ in terms of a Float
 def assert_float(exp, act, msg = nil)
   e, a = exp.to_f, act.to_f
-  if (e.infinite? || a.infinite?) && e != a ||
+  if e.finite? && a.finite? && (n = (e - a).abs) > Mrbtest::FLOAT_TOLERANCE
+    flunk(msg, "    Expected |#{exp} - #{act}| (#{n}) to be <= #{Mrbtest::FLOAT_TOLERANCE}.")
+  elsif (e.infinite? || a.infinite?) && e != a ||
      e.nan? && !a.nan? || !e.nan? && a.nan?
     flunk(msg, "    Expected #{act} to be #{exp}.")
-  elsif (n = (e - a).abs) > Mrbtest::FLOAT_TOLERANCE
-    flunk(msg, "    Expected |#{exp} - #{act}| (#{n}) to be <= #{Mrbtest::FLOAT_TOLERANCE}.")
   else
     pass
   end
@@ -164,8 +302,9 @@ def assert_raise(*exc)
   exc = exc.empty? ? StandardError : exc.size == 1 ? exc[0] : exc
   begin
     yield
-  rescue *exc
+  rescue *exc => e
     pass
+    e
   rescue Exception => e
     diff = "    #{exc} exception expected, not\n" \
            "    Class: <#{e.class}>\n" \
@@ -190,11 +329,33 @@ def assert_nothing_raised(msg = nil)
   end
 end
 
+def assert_raise_with_message(*args, &block)
+  _assert_raise_with_message(:plain, *args, &block)
+end
+def assert_raise_with_message_pattern(*args, &block)
+  _assert_raise_with_message(:pattern, *args, &block)
+end
+def _assert_raise_with_message(type, exc, exp_msg, msg = nil, &block)
+  e = msg ? assert_raise(exc, msg, &block) : assert_raise(exc, &block)
+  e ? ($mrbtest_assert_idx[-1]-=1) : (return e)
+
+  err_msg = e.message
+  unless ret = type == :pattern ? _str_match?(exp_msg, err_msg) : exp_msg == err_msg
+    diff = "    Expected Exception(#{exc}) was raised, but the message doesn't match.\n"
+    if type == :pattern
+      diff += "    Expected #{exp_msg.inspect} to match #{err_msg.inspect}."
+    else
+      diff += assertion_diff(exp_msg, err_msg)
+    end
+  end
+  assert_true(ret, msg, diff)
+end
+
 def pass
   assert_true(true)
 end
 
-def flunk(msg = nil, diff = "Epic Fail!")
+def flunk(msg = "Epic Fail!", diff = "")
   assert_true(false, msg, diff)
 end
 
@@ -208,17 +369,18 @@ def report
     t_print("#{msg}\n")
   end
 
-  $total_test = $ok_test + $ko_test + $kill_test + $skip_test
-  t_print("Total: #{$total_test}\n")
+  $total_test = $ok_test + $ko_test + $kill_test + $warning_test + $skip_test
+  t_print("  Total: #{$total_test}\n")
 
-  t_print("   OK: #{$ok_test}\n")
-  t_print("   KO: #{$ko_test}\n")
-  t_print("Crash: #{$kill_test}\n")
-  t_print(" Skip: #{$skip_test}\n")
+  t_print("     OK: #{$ok_test}\n")
+  t_print("     KO: #{$ko_test}\n")
+  t_print("  Crash: #{$kill_test}\n")
+  t_print("Warning: #{$warning_test}\n")
+  t_print("   Skip: #{$skip_test}\n")
 
   if Object.const_defined?(:Time)
     t_time = Time.now - $test_start
-    t_print(" Time: #{t_time.round(2)} seconds\n")
+    t_print("   Time: #{t_time.round(2)} seconds\n")
   end
 
   $ko_test == 0 && $kill_test == 0
index 2b19fe0..eec31d7 100644 (file)
@@ -298,11 +298,38 @@ assert('Array#size', '15.2.12.5.28') do
 end
 
 assert('Array#slice', '15.2.12.5.29') do
-  a = "12345".slice(1, 3)
-  b = a.slice(0)
-
-  assert_equal("2:", "#{b}:")
-  assert_equal(2, [1,2,3].[](1))
+  a = [*(1..100)]
+  b = a.dup
+
+  assert_equal(1, a.slice(0))
+  assert_equal(100, a.slice(99))
+  assert_nil(a.slice(100))
+  assert_equal(100, a.slice(-1))
+  assert_equal(99,  a.slice(-2))
+  assert_equal(1,   a.slice(-100))
+  assert_nil(a.slice(-101))
+  assert_equal([1],   a.slice(0,1))
+  assert_equal([100], a.slice(99,1))
+  assert_equal([],    a.slice(100,1))
+  assert_equal([100], a.slice(99,100))
+  assert_equal([100], a.slice(-1,1))
+  assert_equal([99],  a.slice(-2,1))
+  assert_equal([10, 11, 12], a.slice(9, 3))
+  assert_equal([10, 11, 12], a.slice(-91, 3))
+  assert_nil(a.slice(-101, 2))
+  assert_equal([1],   a.slice(0..0))
+  assert_equal([100], a.slice(99..99))
+  assert_equal([],    a.slice(100..100))
+  assert_equal([100], a.slice(99..200))
+  assert_equal([100], a.slice(-1..-1))
+  assert_equal([99],  a.slice(-2..-2))
+  assert_equal([10, 11, 12], a.slice(9..11))
+  assert_equal([10, 11, 12], a.slice(-91..-89))
+  assert_equal([10, 11, 12], a.slice(-91..-89))
+  assert_nil(a.slice(-101..-1))
+  assert_nil(a.slice(10, -3))
+  assert_equal([], a.slice(10..7))
+  assert_equal(b, a)
 end
 
 assert('Array#unshift', '15.2.12.5.30') do
@@ -319,11 +346,12 @@ end
 
 assert('Array#to_s', '15.2.12.5.31 / 15.2.12.5.32') do
   a = [2, 3,   4, 5]
+  a[4] = a
   r1 = a.to_s
   r2 = a.inspect
 
   assert_equal(r2, r1)
-  assert_equal("[2, 3, 4, 5]", r1)
+  assert_equal("[2, 3, 4, 5, [...]]", r1)
 end
 
 assert('Array#==', '15.2.12.5.33') do
index 290ecf7..e283911 100644 (file)
@@ -356,6 +356,13 @@ assert('singleton tests') do
       end
     end
   end if Object.const_defined?(:Float)
+
+  o = Object.new
+  sc = class << o; self end
+  o.freeze
+  assert_predicate(sc, :frozen?)
+
+  assert_predicate(class << Object.new.freeze; self end, :frozen?)
 end
 
 assert('clone Class') do
@@ -433,6 +440,25 @@ assert('overriding class variable with a module (#3235)') do
   end
 end
 
+assert('class variable for frozen class/module') do
+  module CVarForFrozenModule
+    freeze
+    assert_raise(FrozenError) { @@cv = 1 }
+  end
+
+  class CVarForFrozenClassA
+    @@a = nil
+    freeze
+  end
+  class CVarForFrozenClassB < CVarForFrozenClassA
+    def a=(v)
+      @@a = v
+    end
+  end
+  b = CVarForFrozenClassB.new
+  assert_raise(FrozenError) { b.a = 1 }
+end
+
 assert('class with non-class/module outer raises TypeError') do
   assert_raise(TypeError) { class 0::C1; end }
   assert_raise(TypeError) { class []::C2; end }
index bef3970..bdb5bff 100644 (file)
@@ -1,16 +1,16 @@
 ##
 # ensure Test
 
-assert('ensure - context - yield') do
-  class EnsureYieldBreak
-    attr_reader :ensure_context
-    def try
-      yield
-    ensure
-      @ensure_context = self
-    end
+class EnsureYieldBreak
+  attr_reader :ensure_context
+  def try
+    yield
+  ensure
+    @ensure_context = self
   end
+end
 
+assert('ensure - context - yield') do
   yielder = EnsureYieldBreak.new
   yielder.try do
   end
@@ -18,15 +18,6 @@ assert('ensure - context - yield') do
 end
 
 assert('ensure - context - yield and break') do
-  class EnsureYieldBreak
-    attr_reader :ensure_context
-    def try
-      yield
-    ensure
-      @ensure_context = self
-    end
-  end
-
   yielder = EnsureYieldBreak.new
   yielder.try do
     break
@@ -35,15 +26,6 @@ assert('ensure - context - yield and break') do
 end
 
 assert('ensure - context - yield and return') do
-  class EnsureYieldBreak
-    attr_reader :ensure_context
-    def try
-      yield
-    ensure
-      @ensure_context = self
-    end
-  end
-
   yielder = EnsureYieldBreak.new
   lambda do
     yielder.try do
index 652c304..9e7602d 100644 (file)
@@ -45,7 +45,7 @@ end
 
 assert('Enumerable#detect', '15.3.2.2.4') do
   assert_equal 1, [1,2,3].detect() { true }
-  assert_equal 'a', [1,2,3].detect("a") { false }
+  assert_equal 'a', [1,2,3].detect(->{"a"}) { false }
 end
 
 assert('Array#each_with_index', '15.3.2.2.5') do
@@ -64,7 +64,7 @@ end
 
 assert('Enumerable#find', '15.3.2.2.7') do
   assert_equal 1, [1,2,3].find() { true }
-  assert_equal 'a', [1,2,3].find("a") { false }
+  assert_equal 'a', [1,2,3].find(->{"a"}) { false }
 end
 
 assert('Enumerable#find_all', '15.3.2.2.8') do
index bdf277c..c9afeb6 100644 (file)
@@ -352,8 +352,10 @@ assert('Exception 19') do
   assert_equal [true, true], Class4Exception19.new.a
 end
 
-assert('Exception#inspect without message') do
+assert('Exception#inspect') do
   assert_equal "Exception", Exception.new.inspect
+  assert_equal "Exception", Exception.new("").inspect
+  assert_equal "error! (Exception)", Exception.new("error!").inspect
 end
 
 assert('Exception#backtrace') do
@@ -398,7 +400,7 @@ assert('GC in rescue') do
     end
   rescue => exception
     GC.start
-    assert_equal("#{__FILE__}:#{line}:in call",
+    assert_equal("#{__FILE__}:#{line}",
                  exception.backtrace.first)
   end
 end
@@ -416,7 +418,7 @@ assert('Method call in rescue') do
   rescue => exception
     [3].each do
     end
-    assert_equal("#{__FILE__}:#{line}:in call",
+    assert_equal("#{__FILE__}:#{line}",
                  exception.backtrace.first)
   end
 end
index 4e9d347..dc98963 100644 (file)
@@ -82,8 +82,8 @@ assert('Float#ceil', '15.2.9.3.8') do
 end
 
 assert('Float#finite?', '15.2.9.3.9') do
-  assert_true 3.123456789.finite?
-  assert_false (1.0 / 0.0).finite?
+  assert_predicate 3.123456789, :finite?
+  assert_not_predicate 1.0 / 0.0, :finite?
 end
 
 assert('Float#floor', '15.2.9.3.10') do
@@ -139,7 +139,7 @@ assert('Float#round', '15.2.9.3.12') do
   nan = 0.0/0.0
   assert_raise(FloatDomainError){ nan.round }
   assert_raise(FloatDomainError){ nan.round(-1) }
-  assert_true(nan.round(1).nan?)
+  assert_predicate(nan.round(1), :nan?)
 end
 
 assert('Float#to_f', '15.2.9.3.13') do
@@ -178,10 +178,10 @@ assert('Float#divmod') do
 end
 
 assert('Float#nan?') do
-  assert_true (0.0/0.0).nan?
-  assert_false 0.0.nan?
-  assert_false (1.0/0.0).nan?
-  assert_false (-1.0/0.0).nan?
+  assert_predicate(0.0/0.0, :nan?)
+  assert_not_predicate(0.0, :nan?)
+  assert_not_predicate(1.0/0.0, :nan?)
+  assert_not_predicate(-1.0/0.0, :nan?)
 end
 
 assert('Float#<<') do
@@ -212,10 +212,10 @@ assert('Float#to_s') do
   assert_equal("Infinity", Float::INFINITY.to_s)
   assert_equal("-Infinity", (-Float::INFINITY).to_s)
   assert_equal("NaN", Float::NAN.to_s)
-  assert_equal("0.0", 0.0.to_s)
-  assert_equal("-0.0", -0.0.to_s)
+  assert_equal("0", 0.0.to_s)
+  assert_equal("-0", -0.0.to_s)
   assert_equal("-3.25", -3.25.to_s)
-  assert_equal("50.0", 50.0.to_s)
+  assert_equal("50", 50.0.to_s)
   assert_equal("0.0125", 0.0125.to_s)
   assert_equal("-0.0125", -0.0125.to_s)
   assert_equal("1.0e-10", 0.0000000001.to_s)
@@ -224,8 +224,8 @@ assert('Float#to_s') do
   assert_equal("-1.0e+20", -1e20.to_s)
   assert_equal("1.0e+16", 10000000000000000.0.to_s)
   assert_equal("-1.0e+16", -10000000000000000.0.to_s)
-  assert_equal("100000.0", 100000.0.to_s)
-  assert_equal("-100000.0", -100000.0.to_s)
+  assert_equal("100000", 100000.0.to_s)
+  assert_equal("-100000", -100000.0.to_s)
   if uses_float
     assert_equal("1.0e+08", 100000000.0.to_s)
     assert_equal("-1.0e+08", -100000000.0.to_s)
@@ -234,15 +234,15 @@ assert('Float#to_s') do
   else
     assert_equal("1.0e+15", 1000000000000000.0.to_s)
     assert_equal("-1.0e+15", -1000000000000000.0.to_s)
-    assert_equal("100000000000000.0", 100000000000000.0.to_s)
-    assert_equal("-100000000000000.0", -100000000000000.0.to_s)
+    assert_equal("100000000000000", 100000000000000.0.to_s)
+    assert_equal("-100000000000000", -100000000000000.0.to_s)
   end
 end
 
 assert('Float#eql?') do
-  assert_true(5.0.eql?(5.0))
-  assert_false(5.0.eql?(5))
-  assert_false(5.0.eql?("5.0"))
+  assert_operator(5.0, :eql?, 5.0)
+  assert_not_operator(5.0, :eql?, 5)
+  assert_not_operator(5.0, :eql?, "5.0")
 end
 
 end # const_defined?(:Float)
index 156991f..cd47d25 100644 (file)
@@ -352,11 +352,13 @@ end
 
 assert('Hash#inspect') do
   h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
+  h["recur"] = h
   ret = h.to_s
 
   assert_include ret, '"c"=>300'
   assert_include ret, '"a"=>100'
   assert_include ret, '"d"=>400'
+  assert_include ret, '"recur"=>{...}'
 end
 
 assert('Hash#rehash') do
index 4ab49eb..f9c44a6 100644 (file)
@@ -154,11 +154,11 @@ assert('Integer#<<', '15.2.8.3.12') do
   # Left Shift by a negative is Right Shift
   assert_equal 23, 46 << -1
 
-  # Left Shift by 31 is bitShift overflow to SignedInt
-  assert_equal 2147483648, 1 << 31
+  skip unless Object.const_defined?(:Float)
 
-  # -3 Left Shift by 30 is bitShift overflow to SignedInt
-  assert_equal(-3221225472, -3 << 30)
+  # Overflow to Fixnum
+  assert_float 9223372036854775808.0, 1 << 63
+  assert_float(-13835058055282163712.0, -3 << 62)
 end
 
 assert('Integer#>>', '15.2.8.3.13') do
@@ -232,8 +232,16 @@ assert('Integer#to_i', '15.2.8.3.24') do
 end
 
 assert('Integer#to_s', '15.2.8.3.25') do
-  assert_equal '1', 1.to_s
-  assert_equal("-1", -1.to_s)
+  assert_equal "1", 1.to_s
+  assert_equal "-1", -1.to_s
+  assert_equal "1010", 10.to_s(2)
+  assert_equal "a", 10.to_s(36)
+  assert_equal "-a", -10.to_s(36)
+  assert_equal "30071", 12345.to_s(8)
+  assert_raise(ArgumentError) { 10.to_s(-1) }
+  assert_raise(ArgumentError) { 10.to_s(0) }
+  assert_raise(ArgumentError) { 10.to_s(1) }
+  assert_raise(ArgumentError) { 10.to_s(37) }
 end
 
 assert('Integer#truncate', '15.2.8.3.26') do
index d99358c..6061501 100644 (file)
@@ -29,11 +29,7 @@ assert('Kernel.block_given?', '15.3.1.2.2') do
   end
 end
 
-# Kernel.eval is provided by the mruby-gem mrbgem. '15.3.1.2.3'
-
-assert('Kernel.global_variables', '15.3.1.2.4') do
-  assert_equal Array, Kernel.global_variables.class
-end
+# Kernel.eval is provided by the mruby-eval mrbgem. '15.3.1.2.3'
 
 assert('Kernel.iterator?', '15.3.1.2.5') do
   assert_false Kernel.iterator?
@@ -63,20 +59,11 @@ assert('Kernel.loop', '15.3.1.2.8') do
   assert_equal 100, i
 end
 
-assert('Kernel.p', '15.3.1.2.9') do
-  # TODO search for a way to test p to stdio
-  assert_true true
-end
+# Kernel.p is provided by the mruby-print mrbgem. '15.3.1.2.9'
 
-assert('Kernel.print', '15.3.1.2.10') do
-  # TODO search for a way to test print to stdio
-  assert_true true
-end
+# Kernel.print is provided by the mruby-print mrbgem. '15.3.1.2.10'
 
-assert('Kernel.puts', '15.3.1.2.11') do
-  # TODO search for a way to test puts to stdio
-  assert_true true
-end
+# Kernel.puts is provided by the mruby-print mrbgem. '15.3.1.2.11'
 
 assert('Kernel.raise', '15.3.1.2.12') do
   assert_raise RuntimeError do
@@ -92,6 +79,24 @@ assert('Kernel#__id__', '15.3.1.3.3') do
   assert_equal Fixnum, __id__.class
 end
 
+assert('Kernel#__send__', '15.3.1.3.4') do
+  # test with block
+  l = __send__(:lambda) do
+    true
+  end
+
+  assert_true l.call
+  assert_equal Proc, l.class
+  # test with argument
+  assert_true __send__(:respond_to?, :nil?)
+  # test without argument and without block
+  assert_equal String, __send__(:to_s).class
+
+  args = [:respond_to?, :nil?]
+  assert_true __send__(*args)
+  assert_equal [:respond_to?, :nil?], args
+end
+
 assert('Kernel#block_given?', '15.3.1.3.6') do
   def bg_try(&b)
     if block_given?
@@ -111,6 +116,13 @@ assert('Kernel#block_given?', '15.3.1.3.6') do
       "block"
     end
   end
+
+  def bg_try_in_block
+    -> { block_given? }[]
+  end
+
+  assert_false bg_try_in_block
+  assert_true bg_try_in_block{}
 end
 
 assert('Kernel#class', '15.3.1.3.7') do
@@ -187,17 +199,6 @@ assert('Kernel#dup', '15.3.1.3.9') do
   a.set(2)
   c = a.dup
 
-  immutables = [ 1, :foo, true, false, nil ]
-  error_count = 0
-  immutables.each do |i|
-    begin
-      i.dup
-    rescue TypeError
-      error_count += 1
-    end
-  end
-
-  assert_equal immutables.size, error_count
   assert_equal 2, a.get
   assert_equal 1, b.get
   assert_equal 2, c.get
@@ -230,6 +231,9 @@ assert('Kernel#extend', '15.3.1.3.13') do
 
   assert_true a.respond_to?(:test_method)
   assert_false b.respond_to?(:test_method)
+
+  assert_raise(FrozenError) { Object.new.freeze.extend(Test4ExtendModule) }
+  assert_raise(FrozenError, TypeError) { :sym.extend(Test4ExtendModule) }
 end
 
 assert('Kernel#extend works on toplevel', '15.3.1.3.13') do
@@ -247,10 +251,23 @@ assert('Kernel#freeze') do
   assert_equal obj, obj.freeze
   assert_equal 0, 0.freeze
   assert_equal :a, :a.freeze
+  assert_equal true, true.freeze
+  assert_equal false, false.freeze
+  assert_equal nil, nil.freeze
+  skip unless Object.const_defined?(:Float)
+  assert_equal 0.0, 0.0.freeze
 end
 
-assert('Kernel#global_variables', '15.3.1.3.14') do
-  assert_equal Array, global_variables.class
+assert('Kernel#frozen?') do
+  assert_false "".frozen?
+  assert_true "".freeze.frozen?
+  assert_true 0.frozen?
+  assert_true :a.frozen?
+  assert_true true.frozen?
+  assert_true false.frozen?
+  assert_true nil.frozen?
+  skip unless Object.const_defined?(:Float)
+  assert_true 0.0.frozen?
 end
 
 assert('Kernel#hash', '15.3.1.3.15') do
@@ -329,17 +346,15 @@ assert('Kernel#method_missing', '15.3.1.3.30') do
     end
   end
   no_super_test = NoSuperMethodTestClass.new
-  begin
+  msg = "undefined method 'no_super_method_named_this'"
+  assert_raise_with_message(NoMethodError, msg) do
     no_super_test.no_super_method_named_this
-  rescue NoMethodError => e
-    assert_equal "undefined method 'no_super_method_named_this'", e.message
   end
 
   a = String.new
-  begin
+  msg = "undefined method 'no_method_named_this'"
+  assert_raise_with_message(NoMethodError, msg) do
     a.no_method_named_this
-  rescue NoMethodError => e
-    assert_equal "undefined method 'no_method_named_this'", e.message
   end
 end
 
@@ -395,6 +410,8 @@ assert('Kernel#remove_instance_variable', '15.3.1.3.41') do
   assert_equal nil, tri.var
   assert_raise(NameError) { tri.remove }
   assert_raise(NameError) { tri.remove_instance_variable(:var) }
+  assert_raise(FrozenError) { tri.freeze.remove }
+  assert_raise(FrozenError, NameError) { :a.remove_instance_variable(:@v) }
 end
 
 # Kernel#require is defined in mruby-require. '15.3.1.3.42'
@@ -471,13 +488,6 @@ assert('Kernel#respond_to_missing?') do
   assert_false Test4RespondToMissing.new.respond_to?(:no_method)
 end
 
-assert('Kernel#global_variables') do
-  variables = global_variables
-  1.upto(9) do |i|
-    assert_equal variables.include?(:"$#{i}"), true
-  end
-end
-
 assert('stack extend') do
   def recurse(count, stop)
     return count if count > stop
index ec36855..12b7f13 100644 (file)
@@ -21,10 +21,29 @@ def labeled_class(name, supklass = Object, &block)
   end
 end
 
+def assert_uninitialized_const(&block)
+  assert_raise_with_message_pattern(NameError, "uninitialized constant *", &block)
+end
+
+def assert_wrong_const_name(&block)
+  assert_raise_with_message_pattern(NameError, "wrong constant name *", &block)
+end
+
 assert('Module', '15.2.2') do
   assert_equal Class, Module.class
 end
 
+assert('Module#alias_method', '15.2.2.4.8') do
+  cls = Class.new do
+    def foo
+      "FOO"
+    end
+  end
+
+  assert_same(cls, cls.alias_method(:bar, :foo))
+  assert_equal("FOO", cls.new.bar)
+end
+
 # TODO not implemented ATM assert('Module.constants', '15.2.2.3.1') do
 
 assert('Module#ancestors', '15.2.2.4.9') do
@@ -48,6 +67,7 @@ assert('Module#append_features', '15.2.2.4.10') do
   end
 
   assert_equal Test4AppendFeatures2, Test4AppendFeatures2.const_get(:Const4AppendFeatures2)
+  assert_raise(FrozenError) { Module.new.append_features Class.new.freeze }
 end
 
 assert('Module#attr NameError') do
@@ -210,7 +230,7 @@ assert('Module#const_defined?', '15.2.2.4.20') do
 
   assert_true Test4ConstDefined.const_defined?(:Const4Test4ConstDefined)
   assert_false Test4ConstDefined.const_defined?(:NotExisting)
-  assert_raise(NameError){ Test4ConstDefined.const_defined?(:wrong_name) }
+  assert_wrong_const_name{ Test4ConstDefined.const_defined?(:wrong_name) }
 end
 
 assert('Module#const_get', '15.2.2.4.21') do
@@ -223,9 +243,9 @@ assert('Module#const_get', '15.2.2.4.21') do
   assert_equal 42, Object.const_get("Test4ConstGet::Const4Test4ConstGet")
 
   assert_raise(TypeError){ Test4ConstGet.const_get(123) }
-  assert_raise(NameError){ Test4ConstGet.const_get(:I_DO_NOT_EXIST) }
-  assert_raise(NameError){ Test4ConstGet.const_get("I_DO_NOT_EXIST::ME_NEITHER") }
-  assert_raise(NameError){ Test4ConstGet.const_get(:wrong_name) }
+  assert_uninitialized_const{ Test4ConstGet.const_get(:I_DO_NOT_EXIST) }
+  assert_uninitialized_const{ Test4ConstGet.const_get("I_DO_NOT_EXIST::ME_NEITHER") }
+  assert_wrong_const_name{ Test4ConstGet.const_get(:wrong_name) }
 end
 
 assert('Module#const_set', '15.2.2.4.23') do
@@ -236,7 +256,7 @@ assert('Module#const_set', '15.2.2.4.23') do
   assert_equal 23, Test4ConstSet.const_set(:Const4Test4ConstSet, 23)
   assert_equal 23, Test4ConstSet.const_get(:Const4Test4ConstSet)
   ["", "wrongNAME", "Wrong-Name"].each do |n|
-    assert_raise(NameError) { Test4ConstSet.const_set(n, 1) }
+    assert_wrong_const_name { Test4ConstSet.const_set(n, 1) }
   end
 end
 
@@ -247,10 +267,13 @@ assert('Module#remove_const', '15.2.2.4.40') do
 
   assert_equal 23, Test4RemoveConst.remove_const(:ExistingConst)
   assert_false Test4RemoveConst.const_defined?(:ExistingConst)
-  assert_raise(NameError) { Test4RemoveConst.remove_const(:NonExistingConst) }
+  assert_raise_with_message_pattern(NameError, "constant * not defined") do
+    Test4RemoveConst.remove_const(:NonExistingConst)
+  end
   %i[x X!].each do |n|
-    assert_raise(NameError) { Test4RemoveConst.remove_const(n) }
+    assert_wrong_const_name { Test4RemoveConst.remove_const(n) }
   end
+  assert_raise(FrozenError) { Test4RemoveConst.freeze.remove_const(:A) }
 end
 
 assert('Module#const_missing', '15.2.2.4.22') do
@@ -263,6 +286,18 @@ assert('Module#const_missing', '15.2.2.4.22') do
   assert_equal 42, Test4ConstMissing.const_get(:ConstDoesntExist)
 end
 
+assert('Module#extend_object', '15.2.2.4.25') do
+  cls = Class.new
+  mod = Module.new { def foo; end }
+  a = cls.new
+  b = cls.new
+  mod.extend_object(b)
+  assert_false a.respond_to?(:foo)
+  assert_true b.respond_to?(:foo)
+  assert_raise(FrozenError) { mod.extend_object(cls.new.freeze) }
+  assert_raise(FrozenError, TypeError) { mod.extend_object(1) }
+end
+
 assert('Module#include', '15.2.2.4.27') do
   module Test4Include
     Const4Include = 42
@@ -276,6 +311,7 @@ assert('Module#include', '15.2.2.4.27') do
 
   assert_equal 42, Test4Include2.const_get(:Const4Include)
   assert_equal Test4Include2, Test4Include2.include_result
+  assert_raise(FrozenError) { Module.new.freeze.include Test4Include }
 end
 
 assert('Module#include?', '15.2.2.4.28') do
@@ -374,6 +410,29 @@ end
 
 # Not ISO specified
 
+assert('Module#dup') do
+  module TestModuleDup
+    @@cvar = :cvar
+    class << self
+      attr_accessor :cattr
+      def cmeth; :cmeth end
+    end
+    def cvar; @@cvar end
+    def imeth; :imeth end
+    self.cattr = :cattr
+  end
+
+  m = TestModuleDup.dup
+  o = Object.include(m).new
+  assert_equal(:cattr, m.cattr)
+  assert_equal(:cmeth, m.cmeth)
+  assert_equal(:cvar, o.cvar)
+  assert_equal(:imeth, o.imeth)
+  assert_match("#<Module:0x*>", m.to_s)
+  assert_not_predicate(m, :frozen?)
+  assert_not_predicate(TestModuleDup.freeze.dup, :frozen?)
+end
+
 assert('Module#define_method') do
   c = Class.new {
     define_method(:m1) { :ok }
@@ -386,6 +445,15 @@ assert('Module#define_method') do
   end
 end
 
+assert 'Module#prepend_features' do
+  mod = Module.new { def m; :mod end }
+  cls = Class.new { def m; :cls end }
+  assert_equal :cls, cls.new.m
+  mod.prepend_features(cls)
+  assert_equal :mod, cls.new.m
+  assert_raise(FrozenError) { Module.new.prepend_features(Class.new.freeze) }
+end
+
 # @!group prepend
   assert('Module#prepend') do
     module M0
@@ -620,6 +688,10 @@ end
   #    end
   #  end;
   #end
+
+  assert 'Module#prepend to frozen class' do
+    assert_raise(FrozenError) { Class.new.freeze.prepend Module.new }
+  end
 # @!endgroup prepend
 
 assert('Module#to_s') do
@@ -640,11 +712,12 @@ assert('Module#to_s') do
   assert_equal 'SetOuter', SetOuter.to_s
   assert_equal 'SetOuter::SetInner', SetOuter::SetInner.to_s
 
-  mod = Module.new
-  cls = Class.new
+  assert_match "#<Module:0x*>", Module.new.to_s
+  assert_match "#<Class:0x*>", Class.new.to_s
 
-  assert_equal "#<Module:0x", mod.to_s[0,11]
-  assert_equal "#<Class:0x", cls.to_s[0,10]
+  assert_equal "FrozenClassToS", (FrozenClassToS = Class.new.freeze).to_s
+  assert_equal "Outer::A", (Outer::A = Module.new.freeze).to_s
+  assert_match "#<Module:0x*>::A", (Module.new::A = Class.new.freeze).to_s
 end
 
 assert('Module#inspect') do
@@ -672,8 +745,8 @@ assert('Issue 1467') do
     include M1
   end
 
-  C1.new
-  C2.new
+  assert_kind_of(M1, C1.new)
+  assert_kind_of(M1, C2.new)
 end
 
 assert('clone Module') do
@@ -687,7 +760,7 @@ assert('clone Module') do
     include M1.clone
   end
 
-  B.new.foo
+  assert_true(B.new.foo)
 end
 
 assert('Module#module_function') do
index d73dfdb..af44a2e 100644 (file)
@@ -1,6 +1,19 @@
 ##
 # Numeric ISO Test
 
+def assert_step(exp, receiver, args, inf: false)
+  act = []
+  ret = receiver.step(*args) do |i|
+    act << i
+    break if inf && exp.size == act.size
+  end
+  expr = "#{receiver.inspect}.step(#{args.map(&:inspect).join(', ')})"
+  assert "assert_step" do
+    assert_true(exp.eql?(act), "#{expr}: counters", assertion_diff(exp, act))
+    assert_same(receiver, ret, "#{expr}: return value") unless inf
+  end
+end
+
 assert('Numeric', '15.2.7') do
   assert_equal(Class, Numeric.class)
 end
@@ -42,31 +55,60 @@ assert('Numeric#**') do
 end
 
 assert('Numeric#step') do
-  assert_step = ->(exp, receiver, args) do
-    inf = !args[0]
-    act = []
-    ret = receiver.step(*args) do |i|
-      act << i
-      break if inf && exp.size == act.size
-    end
-    expr = "#{receiver.inspect}.step(#{args.map(&:inspect).join(', ')})"
-    assert_true(exp.eql?(act), "#{expr}: counters", assertion_diff(exp, act))
-    assert_same(receiver, ret, "#{expr}: return value") unless inf
-  end
-
   assert_raise(ArgumentError) { 1.step(2, 0) { break } }
-  assert_step.([2, 3, 4], 2, [4])
-  assert_step.([10, 8, 6, 4, 2], 10, [1, -2])
-  assert_step.([], 2, [1, 3])
-  assert_step.([], -2, [-1, -3])
-  assert_step.([10, 11, 12, 13], 10, [])
-  assert_step.([10, 7, 4], 10, [nil, -3])
+  assert_step([2, 3, 4], 2, [4])
+  assert_step([10, 8, 6, 4, 2], 10, [1, -2])
+  assert_step([], 2, [1, 3])
+  assert_step([], -2, [-1, -3])
+  assert_step([10, 11, 12, 13], 10, [], inf: true)
+  assert_step([10, 7, 4], 10, [nil, -3], inf: true)
 
   skip unless Object.const_defined?(:Float)
+  inf = Float::INFINITY
   assert_raise(ArgumentError) { 1.step(2, 0.0) { break } }
-  assert_step.([2.0, 3.0, 4.0], 2, [4.0])
-  assert_step.([7.0, 4.0, 1.0, -2.0], 7, [-4, -3.0])
-  assert_step.([2.0, 3.0, 4.0], 2.0, [4])
-  assert_step.([10.0, 11.0, 12.0, 13.0], 10.0, [])
-  assert_step.([10.0, 7.0, 4.0], 10, [nil, -3.0])
+  assert_step([2.0, 3.0, 4.0], 2, [4.0])
+  assert_step([7.0, 4.0, 1.0, -2.0], 7, [-4, -3.0])
+  assert_step([2.0, 3.0, 4.0], 2.0, [4])
+  assert_step([10.0, 11.0, 12.0, 13.0], 10.0, [], inf: true)
+  assert_step([10.0, 7.0, 4.0], 10, [nil, -3.0], inf: true)
+  assert_step([1.0], 1, [nil, inf])
+  assert_step([1.0], 1, [nil, -inf])
+  assert_step([1.0], 1, [3, inf])
+  assert_step([], 1, [-3, inf])
+  assert_step([], 1, [3, -inf])
+  assert_step([1.0], 1, [-3, -inf])
+  assert_step([1.0], 1, [inf, inf])
+  assert_step([], 1, [inf, -inf])
+  assert_step([], 1, [-inf, inf])
+  assert_step([1.0], 1, [-inf, -inf])
+  assert_step([], inf, [2])
+  assert_step([], inf, [-2])
+  assert_step([], inf, [2, 3])
+  assert_step([inf, inf, inf], inf, [2, -3], inf: true)
+  assert_step([], inf, [2, inf])
+  assert_step([inf], inf, [2, -inf])
+  assert_step([], inf, [-2, inf])
+  assert_step([inf], inf, [-2, -inf])
+  assert_step([], inf, [-2, 3])
+  assert_step([inf, inf, inf], inf, [-2, -3], inf: true)
+  assert_step([inf], inf, [inf])
+  assert_step([], inf, [-inf])
+  assert_step([inf], inf, [inf, inf])
+  assert_step([inf], inf, [inf, -inf])
+  assert_step([inf], inf, [-inf, -inf])
+  assert_step([-inf, -inf, -inf], -inf, [2], inf: true)
+  assert_step([-inf, -inf, -inf], -inf, [-2], inf: true)
+  assert_step([-inf, -inf, -inf], -inf, [2, 3], inf: true)
+  assert_step([], -inf, [2, -3])
+  assert_step([-inf], -inf, [2, inf])
+  assert_step([], -inf, [2, -inf])
+  assert_step([-inf], -inf, [-2, inf])
+  assert_step([], -inf, [-2, -inf])
+  assert_step([-inf, -inf, -inf], -inf, [-2, 3], inf: true)
+  assert_step([], -inf, [-2, -3])
+  assert_step([-inf, -inf, -inf], -inf, [inf], inf: true)
+  assert_step([-inf], -inf, [-inf])
+  assert_step([-inf], -inf, [inf, inf])
+  assert_step([], -inf, [inf, -inf])
+  assert_step([-inf], -inf, [-inf, -inf])
 end
index d71fe89..106c286 100644 (file)
@@ -101,12 +101,12 @@ end
 
 assert('Range#dup') do
   r = (1..3).dup
-  assert_equal r.begin, 1
-  assert_equal r.end, 3
+  assert_equal 1, r.begin
+  assert_equal 3, r.end
   assert_false r.exclude_end?
 
   r = ("a"..."z").dup
-  assert_equal r.begin, "a"
-  assert_equal r.end, "z"
+  assert_equal "a", r.begin
+  assert_equal "z", r.end
   assert_true r.exclude_end?
 end
index cf3702c..2bb9888 100644 (file)
@@ -2,7 +2,7 @@
 ##
 # String ISO Test
 
-UTF8STRING = ("\343\201\202".size == 1)
+UTF8STRING = __ENCODING__ == "UTF-8"
 
 assert('String', '15.2.10') do
   assert_equal Class, String.class
@@ -37,49 +37,37 @@ end
 assert('String#*', '15.2.10.5.5') do
   assert_equal 'aaaaa', 'a' * 5
   assert_equal '', 'a' * 0
-  assert_raise(ArgumentError) do
-    'a' * -1
-  end
+  assert_raise(ArgumentError) { 'a' * -1 }
+  assert_raise(TypeError) { 'a' * '1' }
+  assert_raise(TypeError) { 'a' * nil }
+
+  skip unless Object.const_defined?(:Float)
+  assert_equal 'aa', 'a' * 2.1
+  assert_raise(RangeError) { '' * 1e30 }
+  assert_raise(RangeError) { '' * Float::INFINITY }
+  assert_raise(RangeError) { '' * Float::NAN }
 end
 
 assert('String#[]', '15.2.10.5.6') do
   # length of args is 1
-  a = 'abc'[0]
-  b = 'abc'[-1]
-  c = 'abc'[10]
-  d = 'abc'[-10]
-  e = 'abc'[1.1]
+  assert_equal 'a', 'abc'[0]
+  assert_equal 'c', 'abc'[-1]
+  assert_nil 'abc'[10]
+  assert_nil 'abc'[-10]
+  assert_equal 'b', 'abc'[1.1] if Object.const_defined?(:Float)
 
   # length of args is 2
-  a1 = 'abc'[0, -1]
-  b1 = 'abc'[10, 0]
-  c1 = 'abc'[-10, 0]
-  d1 = 'abc'[0, 0]
-  e1 = 'abc'[1, 2]
-
-  # args is RegExp
-  # It will be tested in mrbgems.
+  assert_nil 'abc'[0, -1]
+  assert_nil 'abc'[10, 0]
+  assert_nil 'abc'[-10, 0]
+  assert_equal '', 'abc'[0, 0]
+  assert_equal 'bc', 'abc'[1, 2]
 
   # args is String
-  a3 = 'abc'['bc']
-  b3 = 'abc'['XX']
-
-  assert_equal 'a', 'a'
-  # assert_equal 'c', b
-  # assert_nil c
-  # assert_nil d
-  # assert_equal 'b', e
-  # assert_nil a1
-  # assert_nil b1
-  # assert_nil c1
-  # assert_equal '', d1
-  # assert_equal 'bc', e1
-  # assert_equal 'bc', a3
-  # assert_nil b3
-
-  # assert_raise(TypeError) do
-  #   a[nil]
-  # end
+  assert_equal 'bc', 'abc'['bc']
+  assert_nil 'abc'['XX']
+
+  assert_raise(TypeError) { 'abc'[nil] }
 end
 
 assert('String#[](UTF-8)', '15.2.10.5.6') do
@@ -161,6 +149,9 @@ assert('String#[]=') do
    assert_equal 'aXc', e
   end
 
+  assert_raise(TypeError) { 'a'[0] = 1 }
+  assert_raise(TypeError) { 'a'[:a] = '1' }
+
   # length of args is 2
   a1 = 'abc'
   assert_raise(IndexError) do
@@ -197,8 +188,62 @@ assert('String#[]=') do
   assert_raise(IndexError) do
     b3['XX'] = 'Y'
   end
+
+  assert_raise(TypeError) { 'a'[:a, 0] = '1' }
+  assert_raise(TypeError) { 'a'[0, :a] = '1' }
+  assert_raise(TypeError) { 'a'[0, 1] = 1 }
 end
 
+assert('String[]=(UTF-8)') do
+  a = "➀➁➂➃➄"
+  a[3] = "⚃"
+  assert_equal "➀➁➂⚃➄", a
+
+  b = "➀➁➂➃➄"
+  b[3, 0] = "⛄"
+  assert_equal "➀➁➂⛄➃➄", b
+
+  c = "➀➁➂➃➄"
+  c[3, 2] = "⚃⚄"
+  assert_equal "➀➁➂⚃⚄", c
+
+  d = "➀➁➂➃➄"
+  d[5] = "⛄"
+  assert_equal "➀➁➂➃➄⛄", d
+
+  e = "➀➁➂➃➄"
+  e[5, 0] = "⛄"
+  assert_equal "➀➁➂➃➄⛄", e
+
+  f = "➀➁➂➃➄"
+  f[5, 2] = "⛄"
+  assert_equal "➀➁➂➃➄⛄", f
+
+  g = "➀➁➂➃➄"
+  assert_raise(IndexError) { g[6] = "⛄" }
+
+  h = "➀➁➂➃➄"
+  assert_raise(IndexError) { h[6, 0] = "⛄" }
+
+  i = "➀➁➂➃➄"
+  assert_raise(IndexError) { i[6, 2] = "⛄" }
+
+  j = "➀➁➂➃➄"
+  j["➃"] = "⚃"
+  assert_equal "➀➁➂⚃➄", j
+
+  k = "➀➁➂➃➄"
+  assert_raise(IndexError) { k["⛄"] = "⛇" }
+
+  l = "➀➁➂➃➄"
+  assert_nothing_raised { l["➂"] = "" }
+  assert_equal "➀➁➃➄", l
+
+  m = "➀➁➂➃➄"
+  assert_raise(TypeError) { m["➂"] = nil }
+  assert_equal "➀➁➂➃➄", m
+end if UTF8STRING
+
 assert('String#capitalize', '15.2.10.5.7') do
   a = 'abc'
   a.capitalize
@@ -406,7 +451,22 @@ assert('String#index', '15.2.10.5.22') do
   assert_equal 3, 'abcabc'.index('a', 1)
   assert_equal 5, "hello".index("", 5)
   assert_equal nil, "hello".index("", 6)
-end
+  assert_equal 3, "hello".index("l", -2)
+  assert_raise(ArgumentError) { "hello".index }
+  assert_raise(TypeError) { "hello".index(101) }
+end
+
+assert('String#index(UTF-8)', '15.2.10.5.22') do
+  assert_equal 0, '⓿➊➋➌➍➎'.index('⓿')
+  assert_nil '⓿➊➋➌➍➎'.index('➓')
+  assert_equal 6, '⓿➊➋➌➍➎⓿➊➋➌➍➎'.index('⓿', 1)
+  assert_equal 6, '⓿➊➋➌➍➎⓿➊➋➌➍➎'.index('⓿', -7)
+  assert_equal 6, "⓿➊➋➌➍➎".index("", 6)
+  assert_equal nil, "⓿➊➋➌➍➎".index("", 7)
+  assert_equal 0, '⓿➊➋➌➍➎'.index("\xe2")
+  assert_equal nil, '⓿➊➋➌➍➎'.index("\xe3")
+  assert_equal 6, "\xd1\xd1\xd1\xd1\xd1\xd1⓿➊➋➌➍➎".index('⓿')
+end if UTF8STRING
 
 assert('String#initialize', '15.2.10.5.23') do
   a = ''
@@ -469,6 +529,7 @@ assert('String#reverse(UTF-8)', '15.2.10.5.29') do
 
   assert_equal 'こんにちは世界!', a
   assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse
+  assert_equal 'あ', 'あ'.reverse
 end if UTF8STRING
 
 assert('String#reverse!', '15.2.10.5.30') do
@@ -485,24 +546,44 @@ assert('String#reverse!(UTF-8)', '15.2.10.5.30') do
 
   assert_equal '!界世はちにんこ', a
   assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse!
+
+  b = 'あ'
+  b.reverse!
+  assert_equal 'あ', b
 end if UTF8STRING
 
 assert('String#rindex', '15.2.10.5.31') do
   assert_equal 0, 'abc'.rindex('a')
+  assert_equal 0, 'abc'.rindex('a', 3)
+  assert_nil 'abc'.rindex('a', -4)
   assert_nil 'abc'.rindex('d')
+  assert_equal 6, 'abcabc'.rindex('')
+  assert_equal 3, 'abcabc'.rindex('a')
   assert_equal 0, 'abcabc'.rindex('a', 1)
   assert_equal 3, 'abcabc'.rindex('a', 4)
+  assert_equal 0, 'abcabc'.rindex('a', -4)
+  assert_raise(ArgumentError) { "hello".rindex }
+  assert_raise(TypeError) { "hello".rindex(101) }
 end
 
 assert('String#rindex(UTF-8)', '15.2.10.5.31') do
   str = "こんにちは世界!\nこんにちは世界!"
-  assert_nil str.index('さ')
-  assert_equal 3, str.index('ち')
-  assert_equal 12, str.index('ち', 10)
-  assert_equal nil, str.index("さ")
+  assert_nil str.rindex('さ')
+  assert_equal 12, str.rindex('ち')
+  assert_equal 3, str.rindex('ち', 10)
+  assert_equal 3, str.rindex('ち', -6)
+
+  broken = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃"
+  assert_nil broken.rindex("\x81") # "\x81" is a part of "☁" ("\xe2\x98\x81")
+  assert_equal 11, broken.rindex("☁")
+  assert_equal 11, broken.rindex("☁", 12)
+  assert_equal 11, broken.rindex("☁", 11)
+  assert_equal  3, broken.rindex("☁", 10)
 end if UTF8STRING
 
-# 'String#scan', '15.2.10.5.32' will be tested in mrbgems.
+# assert('String#scan', '15.2.10.5.32') do
+#   # Not implemented yet
+# end
 
 assert('String#size', '15.2.10.5.33') do
   assert_equal 3, 'abc'.size
@@ -606,31 +687,45 @@ assert('String#sub!', '15.2.10.5.37') do
 end
 
 assert('String#to_f', '15.2.10.5.38') do
-  a = ''.to_f
-  b = '123456789'.to_f
-  c = '12345.6789'.to_f
-  d = '1e-2147483648'.to_f
-  e = '1e2147483648'.to_f
-
-  assert_float(0.0, a)
-  assert_float(123456789.0, b)
-  assert_float(12345.6789, c)
-  assert_float(0, d)
-  assert_float(Float::INFINITY, e)
+  assert_operator(0.0, :eql?, ''.to_f)
+  assert_operator(123456789.0, :eql?, '123456789'.to_f)
+  assert_operator(12345.6789, :eql?, '12345.6789'.to_f)
+  assert_operator(0.0, :eql?, '1e-2147483648'.to_f)
+  assert_operator(Float::INFINITY, :eql?, '1e2147483648'.to_f)
+  assert_operator(0.0, :eql?, 'a'.to_f)
+  assert_operator(4.0, :eql?, '4a5'.to_f)
+  assert_operator(12.0, :eql?, '1_2__3'.to_f)
+  assert_operator(123.0, :eql?, '1_2_3'.to_f)
+  assert_operator(68.0, :eql?, '68_'.to_f)
+  assert_operator(68.0, :eql?, '68._7'.to_f)
+  assert_operator(68.7, :eql?, '68.7_'.to_f)
+  assert_operator(68.7, :eql?, '68.7_ '.to_f)
+  assert_operator(6.0, :eql?, '6 8.7'.to_f)
+  assert_operator(68.0, :eql?, '68. 7'.to_f)
+  assert_operator(0.0, :eql?, '_68'.to_f)
+  assert_operator(0.0, :eql?, ' _68'.to_f)
+  assert_operator(12.34, :eql?, '1_2.3_4'.to_f)
+  assert_operator(12.3, :eql?, '1_2.3__4'.to_f)
+  assert_operator(0.9, :eql?, '.9'.to_f)
+  assert_operator(0.9, :eql?, "\t\r\n\f\v .9 \t\r\n\f\v".to_f)
 end if Object.const_defined?(:Float)
 
 assert('String#to_i', '15.2.10.5.39') do
-  a = ''.to_i
-  b = '32143'.to_i
-  c = 'a'.to_i(16)
-  d = '100'.to_i(2)
-  e = '1_000'.to_i
-
-  assert_equal 0, a
-  assert_equal 32143, b
-  assert_equal 10, c
-  assert_equal 4, d
-  assert_equal 1_000, e
+  assert_operator 0, :eql?, ''.to_i
+  assert_operator 32143, :eql?, '32143'.to_i
+  assert_operator 10, :eql?, 'a'.to_i(16)
+  assert_operator 4, :eql?, '100'.to_i(2)
+  assert_operator 1_000, :eql?, '1_000'.to_i
+  assert_operator 0, :eql?, 'a'.to_i
+  assert_operator 4, :eql?, '4a5'.to_i
+  assert_operator 12, :eql?, '1_2__3'.to_i
+  assert_operator 123, :eql?, '1_2_3'.to_i
+  assert_operator 68, :eql?, '68_'.to_i
+  assert_operator 68, :eql?, '68_ '.to_i
+  assert_operator 0, :eql?, '_68'.to_i
+  assert_operator 0, :eql?, ' _68'.to_i
+  assert_operator 68, :eql?, "\t\r\n\f\v 68 \t\r\n\f\v".to_i
+  assert_operator 6, :eql?, ' 6 8 '.to_i
 end
 
 assert('String#to_s', '15.2.10.5.40') do
@@ -667,12 +762,18 @@ assert('String#upcase!', '15.2.10.5.43') do
 end
 
 assert('String#inspect', '15.2.10.5.46') do
+  assert_equal "\"\\x00\"", "\0".inspect
+  assert_equal "\"foo\"", "foo".inspect
+  if UTF8STRING
+    assert_equal '"る"', "る".inspect
+  else
+    assert_equal '"\xe3\x82\x8b"', "る".inspect
+  end
+
   # should not raise an exception - regress #1210
   assert_nothing_raised do
-  ("\1" * 100).inspect
+    ("\1" * 100).inspect
   end
-
-  assert_equal "\"\\x00\"", "\0".inspect
 end
 
 # Not ISO specified
@@ -682,10 +783,6 @@ assert('String interpolation (mrb_str_concat for shared strings)') do
   assert_equal "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:", "#{a}:"
 end
 
-assert('Check the usage of a NUL character') do
-  "qqq\0ppp"
-end
-
 assert('String#bytes') do
   str1 = "hello"
   bytes1 = [104, 101, 108, 108, 111]
@@ -719,3 +816,82 @@ assert('String literal concatenation') do
   assert_equal 3, ('A' "B" 'C').size
   assert_equal 4, (%(A) "B#{?C}" "D").size
 end
+
+assert('String#getbyte') do
+  str1 = "hello"
+  bytes1 = [104, 101, 108, 108, 111]
+  assert_equal bytes1[0], str1.getbyte(0)
+  assert_equal bytes1[-1], str1.getbyte(-1)
+  assert_equal bytes1[6], str1.getbyte(6)
+
+  str2 = "\xFF"
+  bytes2 = [0xFF]
+  assert_equal bytes2[0], str2.getbyte(0)
+end
+
+assert('String#setbyte') do
+  str1 = "hello"
+  h = "H".getbyte(0)
+  str1.setbyte(0, h)
+  assert_equal(h, str1.getbyte(0))
+  assert_equal("Hello", str1)
+end
+
+assert('String#byteslice') do
+  str1 = "hello"
+  str2 = "\u3042ab"  # "\xE3\x81\x82ab"
+
+  assert_equal("h", str1.byteslice(0))
+  assert_equal("e", str1.byteslice(1))
+  assert_equal(nil, str1.byteslice(5))
+  assert_equal("o", str1.byteslice(-1))
+  assert_equal(nil, str1.byteslice(-6))
+  assert_equal("\xE3", str2.byteslice(0))
+  assert_equal("\x81", str2.byteslice(1))
+  assert_equal(nil, str2.byteslice(5))
+  assert_equal("b", str2.byteslice(-1))
+  assert_equal(nil, str2.byteslice(-6))
+
+  assert_equal("", str1.byteslice(0, 0))
+  assert_equal(str1, str1.byteslice(0, 6))
+  assert_equal("el", str1.byteslice(1, 2))
+  assert_equal("", str1.byteslice(5, 1))
+  assert_equal("o", str1.byteslice(-1, 6))
+  assert_equal(nil, str1.byteslice(-6, 1))
+  assert_equal(nil, str1.byteslice(0, -1))
+  assert_equal("", str2.byteslice(0, 0))
+  assert_equal(str2, str2.byteslice(0, 6))
+  assert_equal("\x81\x82", str2.byteslice(1, 2))
+  assert_equal("", str2.byteslice(5, 1))
+  assert_equal("b", str2.byteslice(-1, 6))
+  assert_equal(nil, str2.byteslice(-6, 1))
+  assert_equal(nil, str2.byteslice(0, -1))
+
+  assert_equal("ell", str1.byteslice(1..3))
+  assert_equal("el", str1.byteslice(1...3))
+  assert_equal("h", str1.byteslice(0..0))
+  assert_equal("", str1.byteslice(5..0))
+  assert_equal("o", str1.byteslice(4..5))
+  assert_equal(nil, str1.byteslice(6..0))
+  assert_equal("", str1.byteslice(-1..0))
+  assert_equal("llo", str1.byteslice(-3..5))
+  assert_equal("\x81\x82a", str2.byteslice(1..3))
+  assert_equal("\x81\x82", str2.byteslice(1...3))
+  assert_equal("\xE3", str2.byteslice(0..0))
+  assert_equal("", str2.byteslice(5..0))
+  assert_equal("b", str2.byteslice(4..5))
+  assert_equal(nil, str2.byteslice(6..0))
+  assert_equal("", str2.byteslice(-1..0))
+  assert_equal("\x82ab", str2.byteslice(-3..5))
+
+  assert_raise(ArgumentError) { str1.byteslice }
+  assert_raise(ArgumentError) { str1.byteslice(1, 2, 3) }
+  assert_raise(TypeError) { str1.byteslice("1") }
+  assert_raise(TypeError) { str1.byteslice("1", 2) }
+  assert_raise(TypeError) { str1.byteslice(1, "2") }
+  assert_raise(TypeError) { str1.byteslice(1..2, 3) }
+
+  skip unless Object.const_defined?(:Float)
+  assert_equal("o", str1.byteslice(4.0))
+  assert_equal("\x82ab", str2.byteslice(2.0, 3.0))
+end
index 603547c..436c066 100644 (file)
@@ -423,10 +423,11 @@ assert('parenthesed do-block in cmdarg') do
 end
 
 assert('method definition in cmdarg') do
-  if false
+  result = class MethodDefinitionInCmdarg
+    def self.bar(arg); arg end
     bar def foo; self.each do end end
   end
-  true
+  assert_equal(:foo, result)
 end
 
 assert('optional argument in the rhs default expressions') do
@@ -450,6 +451,18 @@ assert('optional block argument in the rhs default expressions') do
   assert_nil(Proc.new {|foo = foo| foo}.call)
 end
 
+assert('local variable definition in default value and subsequent arguments') do
+  def m(a = b = 1, c) [a, b, c] end
+  assert_equal([1, 1, :c], m(:c))
+  assert_equal([:a, nil, :c], m(:a, :c))
+
+  def m(a = b = 1, &c) [a, b, c ? true : nil] end
+  assert_equal([1, 1, nil], m)
+  assert_equal([1, 1, true], m{})
+  assert_equal([:a, nil, nil], m(:a))
+  assert_equal([:a, nil, true], m(:a){})
+end
+
 assert('multiline comments work correctly') do
 =begin
 this is a comment with nothing after begin and end
@@ -653,4 +666,18 @@ assert 'keyword arguments' do
   result = m(1, 2, e: 3, g: 4, h: 5, i: 6, &(l = ->{}))
   assert_equal([1, 1, [], 2, 3, 2, 4, { h: 5, i: 6 }, l], result)
 =end
+
+  def m(a: b = 1, c:) [a, b, c] end
+  assert_equal([1, 1, :c], m(c: :c))
+  assert_equal([:a, nil, :c], m(a: :a, c: :c))
+end
+
+assert('numbered parameters') do
+  assert_equal(15, [1,2,3,4,5].reduce {_1+_2})
+  assert_equal(45, Proc.new do _1 + _2 + _3 + _4 + _5 + _6 + _7 + _8 + _9 end.call(*[1, 2, 3, 4, 5, 6, 7, 8, 9]))
+end
+
+assert('_0 is not numbered parameter') do
+  _0 = :l
+  assert_equal(:l, ->{_0}.call)
 end
diff --git a/third-party/mruby/test/t/vformat.rb b/third-party/mruby/test/t/vformat.rb
new file mode 100644 (file)
index 0000000..df6950e
--- /dev/null
@@ -0,0 +1,58 @@
+# coding: utf-8-emacs
+def sclass(v)
+  class << v
+    self
+  end
+end
+
+assert('mrb_vformat') do
+  vf = TestVFormat
+  assert_equal '', vf.z('')
+  assert_equal 'No specifier!', vf.z('No specifier!')
+  assert_equal '`c`: C', vf.c('`c`: %c', ?C)
+  assert_equal '`d`: 123', vf.d('`d`: %d', 123)
+  assert_equal '`d`: -79', vf.d('`d`: %d', -79)
+  assert_equal '`i`: 514', vf.i('`i`: %i', 514)
+  assert_equal '`i`: -83', vf.i('`i`: %i', -83)
+  assert_equal '`t`: NilClass', vf.v('`t`: %t', nil)
+  assert_equal '`t`: FalseClass', vf.v('`t`: %t', false)
+  assert_equal '`t`: TrueClass', vf.v('`t`: %t', true)
+  assert_equal '`t`: Fixnum', vf.v('`t`: %t', 0)
+  assert_equal '`t`: Hash', vf.v('`t`: %t', {k: "value"})
+  assert_match '#<Class:#<Class:#<Hash:0x*>>>', vf.v('%t', sclass({}))
+  assert_equal 'string and length', vf.l('string %l length', 'andante', 3)
+  assert_equal '`n`: sym', vf.n('`n`: %n', :sym)
+  assert_equal '%C文字列%', vf.s('%s', '%C文字列%')
+  assert_equal '`C`: Kernel module', vf.C('`C`: %C module', Kernel)
+  assert_equal '`C`: NilClass', vf.C('`C`: %C', nil.class)
+  assert_match '#<Class:#<String:0x*>>', vf.C('%C', sclass(""))
+  assert_equal '`T`: NilClass', vf.v('`T`: %T', nil)
+  assert_equal '`T`: FalseClass', vf.v('`T`: %T', false)
+  assert_equal '`T`: TrueClass', vf.v('`T`: %T', true)
+  assert_equal '`T`: Fixnum', vf.v('`T`: %T', 0)
+  assert_equal '`T`: Hash', vf.v('`T`: %T', {k: "value"})
+  assert_match 'Class', vf.v('%T', sclass({}))
+  assert_equal '`Y`: nil', vf.v('`Y`: %Y', nil)
+  assert_equal '`Y`: false', vf.v('`Y`: %Y', false)
+  assert_equal '`Y`: true', vf.v('`Y`: %Y', true)
+  assert_equal '`Y`: Fixnum', vf.v('`Y`: %Y', 0)
+  assert_equal '`Y`: Hash', vf.v('`Y`: %Y', {k: "value"})
+  assert_equal 'Class', vf.v('%Y', sclass({}))
+  assert_match '#<Class:#<String:0x*>>', vf.v('%v', sclass(""))
+  assert_equal '`v`: 1...3', vf.v('`v`: %v', 1...3)
+  assert_equal '`S`: {:a=>1, "b"=>"c"}', vf.v('`S`: %S', {a: 1, "b" => ?c})
+  assert_equal 'percent: %', vf.z('percent: %%')
+  assert_equal '"I": inspect char', vf.c('%!c: inspect char', ?I)
+  assert_equal '709: inspect mrb_int', vf.i('%!d: inspect mrb_int', 709)
+  assert_equal '"a\x00b\xff"', vf.l('%!l', "a\000b\xFFc\000d", 4)
+  assert_equal ':"&.": inspect symbol', vf.n('%!n: inspect symbol', :'&.')
+  assert_equal 'inspect "String"', vf.v('inspect %!v', 'String')
+  assert_equal 'inspect Array: [1, :x, {}]', vf.v('inspect Array: %!v', [1,:x,{}])
+  assert_match '`!C`: #<Class:0x*>', vf.C('`!C`: %!C', Class.new)
+  assert_equal 'escape: \\%a,b,c,d', vf.v('escape: \\\\\%a,b,\c%v', ',d')
+
+  skip unless Object.const_defined?(:Float)
+  assert_equal '`f`: 0.0125', vf.f('`f`: %f', 0.0125)
+  assert_equal '-Infinity', vf.f('%f', -Float::INFINITY)
+  assert_equal 'NaN: Not a Number', vf.f('%f: Not a Number', Float::NAN)
+end
index e12bae6..f4bef0a 100644 (file)
@@ -1,24 +1,11 @@
-MRuby::Build.new('debug') do |conf|
-  toolchain :gcc
-  enable_debug
-
-  # include all core GEMs
-  conf.gembox 'full-core'
-  conf.cc.flags += %w(-Werror=declaration-after-statement)
-  conf.compilers.each do |c|
-    c.defines += %w(MRB_GC_STRESS MRB_GC_FIXED_ARENA MRB_METHOD_CACHE)
-  end
-
-  build_mrbc_exec
-end
-
 MRuby::Build.new('full-debug') do |conf|
   toolchain :gcc
   enable_debug
 
   # include all core GEMs
   conf.gembox 'full-core'
-  conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK)
+  conf.cc.flags += %w(-Werror=declaration-after-statement)
+  conf.cc.defines += %w(MRB_GC_STRESS MRB_METHOD_CACHE MRB_ENABLE_DEBUG_HOOK)
 
   conf.enable_test
 end
@@ -40,7 +27,7 @@ MRuby::Build.new('cxx_abi') do |conf|
   toolchain :gcc
 
   conf.gembox 'full-core'
-  conf.cc.flags += %w(-Werror=declaration-after-statement -fpermissive)
+  conf.cc.flags += %w(-fpermissive)
   conf.compilers.each do |c|
     c.defines += %w(MRB_GC_FIXED_ARENA)
   end